General Context
This test drives the Cryptocalc application as a real user would, through its Electron GUI.
It launches a fresh instance of the application, performs UI interactions, and verifies
the resulting state of wallet fields as well as files saved in the _output/ folder.
Confirmed Application Behavior
Save
No file-picker. Direct write to
_output/<timestamp>_<COIN>_<LANG>/ followed by an iziToast with "Show" and "Close" buttonsOpen
Native OS dialog to choose the file — mocked via
electronApp.evaluate({ dialog })Key Technical Constraints
#account_id, #address_index_id
Read-only fields — modified via
page.evaluate() to bypass Playwright's refusal to fill readonly inputs#refresh_btn_id, #save_icon_id, #file_open_icon_id
May be
disabled — clicked via evaluate() after removing the disabled attributeAddress generation
Asynchronous — 5s pause after each
clickRefresh()Save operation
5s wait after iziToast appears to allow file writes to complete
_output/ directory
Cleaned before each test to prevent interference
Shared Helpers
switchToHDWallet(page)Navigate to Wallet tab, select "HD Wallet" mode
selectBlockchain(page, blockchain)Select a blockchain from the dynamic dropdown
setFieldValue(page, id, val)Inject a value into any field (readonly-safe), dispatches input + change
clickRefresh(page)Trigger refresh via evaluate() — generates a new address
getDisplayedAddress(page)Read the current text content of
#address_idsaveWallet(page)Click Save, wait for iziToast, dismiss it, and return the path to the created .wits file
openWallet(page, electronApp, filePath)Mock the open dialog and click the open icon
logWalletState(page, label)Log the state of main fields for debugging
cleanupOutputDir()Delete all folders and files in
_output/Test Protocol
01
Complete Workflow
Generate, save, open, and modify a Dogecoin HD wallet
Objective
Verify the complete lifecycle of a Dogecoin HD wallet:
Phase 1 Initial setup (account=1, index=3)
Phase 2 Generation + address format validation
Phase 3 Save → verify JSON file in _output/
Phase 4 Reopen file → verify reload
Phase 5 Modify (account=4, index=7) + refresh
Phase 6 Second save → verify update
Preconditions
App launched & ready
Wallet tab active
Mode: HD Wallet
Blockchain: Dogecoin
_output/ folder empty
Detailed Phases
| Phase | Action | Method |
|---|---|---|
| 1 | Set account=1, index=3 | setFieldValue(page, 'account_id', '1') setFieldValue(page, 'address_index_id', '3') |
| 2 | Trigger address generation | clickRefresh(page) |
| 2b | Read generated address | getDisplayedAddress(page) → initialAddress |
| Phase | Action | Method |
|---|---|---|
| 3 | Save wallet | saveWallet(page) → savedPath1 |
| 3b | Verify file exists | fs.existsSync(savedPath1) === true |
| 3c | Verify JSON contains address | JSON.parse() .includes(initialAddress) |
| Phase | Action | Method |
|---|---|---|
| 4 | Open saved file | openWallet(page, electronApp, savedPath1) |
| 4b | Read reloaded address | getDisplayedAddress(page) → reloadedAddress |
| Phase | Action | Method |
|---|---|---|
| 5 | Modify account=4, index=7 | setFieldValue(page, 'account_id', '4') setFieldValue(page, 'address_index_id', '7') |
| 5b | Refresh | clickRefresh(page) |
| 5c | Read new address | getDisplayedAddress(page) → updatedAddress |
| Phase | Action | Method |
|---|---|---|
| 6 | Save modified wallet | saveWallet(page) → savedPath2 |
| 6b | Verify second file exists | fs.existsSync(savedPath2) === true |
| 6c | Verify JSON contains new address | JSON.parse() .includes(updatedAddress) |
| 6d | Verify old address is not present | ! .includes(initialAddress) |
Assertions
/^D[1-9A-HJ-NP-Za-km-z]{32,34}$/ ← valid Dogecoin address format
updatedAddress ≠ initialAddress
reloadedAddress = initialAddress
Failure Scenarios
- ✗Empty address — generation did not complete within timeout
- ✗Invalid address format — regex not satisfied (wrong blockchain or derivation error)
- ✗No file created — save failed (incorrect path or write error)
- ✗reloadedAddress ≠ initialAddress — open did not properly reload the wallet
- ✗updatedAddress = initialAddress — parameter changes were not applied
- ✗Second file contains old address — update was not saved
Implementation Note
Open dialog mock: Attempting to mock via
Cleanup: The
electronApp.evaluate() may fail with
ReferenceError: require is not defined. The test is designed to continue even if the mock fails —
in that case, the real system dialog would appear, but in CI/headless environments, the application typically
uses a default path or the test is configured to run without user interaction.Cleanup: The
_output/ folder is completely cleaned before each test to ensure
no residual files from previous runs interfere.
Summary