-
-
Notifications
You must be signed in to change notification settings - Fork 280
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(e2e): Refactors locators and methods of dashboard and settin…
…gs PO (#15594) refactors locators, they are now defined as page object class properties splits onboarding page object from dashboard simplifies majority of methods, removes plenty of redundant one
- Loading branch information
Showing
11 changed files
with
172 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 30 additions & 50 deletions
80
packages/suite-desktop-core/e2e/support/pageActions/dashboardActions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,52 @@ | ||
import { Page, expect } from '@playwright/test'; | ||
import { Locator, Page, expect } from '@playwright/test'; | ||
|
||
import { NetworkSymbol } from '@suite-common/wallet-config'; | ||
|
||
import { waitForDataTestSelector } from '../common'; | ||
|
||
export class DashboardActions { | ||
private readonly window: Page; | ||
readonly discoveryBar: Locator; | ||
readonly dashboardGraph: Locator; | ||
readonly deviceSwitchingOpenButton: Locator; | ||
readonly modal: Locator; | ||
readonly walletAtIndex = (index: number) => | ||
this.window.getByTestId(`@switch-device/wallet-on-index/${index}`); | ||
readonly walletAtIndexEjectButton = (index: number) => | ||
this.window.getByTestId(`@switch-device/wallet-on-index/${index}/eject-button`); | ||
readonly confirmDeviceEjectButton: Locator; | ||
readonly addStandardWalletButton: Locator; | ||
readonly balanceOfNetwork = (network: NetworkSymbol) => | ||
this.window.getByTestId(`@wallet/coin-balance/value-${network}`); | ||
|
||
constructor(window: Page) { | ||
this.window = window; | ||
} | ||
optionallyDismissFwHashCheckError() { | ||
// dismiss the error modal only if it appears (handle it async in parallel, not necessary to block the rest of the flow) | ||
this.window | ||
.$('[data-testid="@device-compromised/back-button"]') | ||
.then(dismissFwHashCheckButton => dismissFwHashCheckButton?.click()); | ||
} | ||
|
||
async passThroughInitialRun() { | ||
await waitForDataTestSelector(this.window, '@welcome/title'); | ||
this.optionallyDismissFwHashCheckError(); | ||
await this.window.getByTestId('@analytics/continue-button').click(); | ||
await this.window.getByTestId('@onboarding/exit-app-button').click(); | ||
|
||
await this.window.getByTestId('@onboarding/viewOnly/skip').click(); | ||
await this.window.getByTestId('@viewOnlyTooltip/gotIt').click(); | ||
this.discoveryBar = this.window.getByTestId('@wallet/discovery-progress-bar'); | ||
this.dashboardGraph = this.window.getByTestId('@dashboard/graph'); | ||
this.deviceSwitchingOpenButton = this.window.getByTestId('@menu/switch-device'); | ||
this.modal = this.window.getByTestId('@modal'); | ||
this.confirmDeviceEjectButton = this.window.getByTestId('@switch-device/eject'); | ||
this.addStandardWalletButton = this.window.getByTestId('@switch-device/add-wallet-button'); | ||
} | ||
|
||
async discoveryShouldFinish() { | ||
const discoveryBarSelector = '@wallet/discovery-progress-bar'; | ||
await waitForDataTestSelector(this.window, discoveryBarSelector, { | ||
state: 'attached', | ||
timeout: 10_000, | ||
}); | ||
await waitForDataTestSelector(this.window, discoveryBarSelector, { | ||
state: 'detached', | ||
timeout: 120_000, | ||
}); | ||
await waitForDataTestSelector(this.window, '@dashboard/graph', { timeout: 30000 }); | ||
await this.discoveryBar.waitFor({ state: 'attached', timeout: 10_000 }); | ||
await this.discoveryBar.waitFor({ state: 'detached', timeout: 120_000 }); | ||
await expect(this.dashboardGraph).toBeVisible(); | ||
} | ||
|
||
async openDeviceSwitcher() { | ||
await this.window.getByTestId('@menu/switch-device').click(); | ||
const deviceSwitcherModal = this.window.getByTestId('@modal'); | ||
await deviceSwitcherModal.waitFor({ state: 'visible' }); | ||
await this.deviceSwitchingOpenButton.click(); | ||
await expect(this.modal).toBeVisible(); | ||
} | ||
|
||
async ejectWallet(walletIndex: number = 0) { | ||
const wallet = this.window.locator( | ||
`[data-testid="@switch-device/wallet-on-index/${walletIndex}"]`, | ||
); | ||
await this.window | ||
.locator('[data-testid="@switch-device/wallet-on-index/0/eject-button"]') | ||
.click(); | ||
await this.window.locator('[data-testid="@switch-device/eject"]').click(); | ||
await wallet.waitFor({ state: 'detached' }); | ||
await this.walletAtIndexEjectButton(walletIndex).click(); | ||
await this.confirmDeviceEjectButton.click(); | ||
await this.walletAtIndex(walletIndex).waitFor({ state: 'detached' }); | ||
} | ||
|
||
async addStandardWallet() { | ||
const addStandardWallet = this.window.getByTestId('@switch-device/add-wallet-button'); | ||
await addStandardWallet.click(); | ||
await this.window.getByTestId('@modal').waitFor({ state: 'detached' }); | ||
await this.addStandardWalletButton.click(); | ||
await this.modal.waitFor({ state: 'detached' }); | ||
await this.discoveryShouldFinish(); | ||
} | ||
|
||
// asserts | ||
async assertHasVisibleBalanceOnFirstAccount(network: NetworkSymbol) { | ||
const locator = this.window.getByTestId(`@wallet/coin-balance/value-${network}`).first(); | ||
|
||
await expect(locator).toBeVisible(); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
packages/suite-desktop-core/e2e/support/pageActions/onboardingActions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { Locator, Page, expect } from '@playwright/test'; | ||
|
||
export class OnboardingActions { | ||
private readonly window: Page; | ||
readonly welcomeTitle: Locator; | ||
readonly analyticsContinueButton: Locator; | ||
readonly onboardingContinueButton: Locator; | ||
readonly onboardingViewOnlySkipButton: Locator; | ||
readonly viewOnlyTooltipGotItButton: Locator; | ||
|
||
constructor(window: Page) { | ||
this.window = window; | ||
this.welcomeTitle = this.window.getByTestId('@welcome/title'); | ||
this.analyticsContinueButton = this.window.getByTestId('@analytics/continue-button'); | ||
this.onboardingContinueButton = this.window.getByTestId('@onboarding/exit-app-button'); | ||
this.onboardingViewOnlySkipButton = this.window.getByTestId('@onboarding/viewOnly/skip'); | ||
this.viewOnlyTooltipGotItButton = this.window.getByTestId('@viewOnlyTooltip/gotIt'); | ||
} | ||
|
||
optionallyDismissFwHashCheckError() { | ||
// dismisses the error modal only if it appears (handle it async in parallel, not necessary to block the rest of the flow) | ||
this.window | ||
.$('[data-testid="@device-compromised/back-button"]') | ||
.then(dismissFwHashCheckButton => dismissFwHashCheckButton?.click()); | ||
} | ||
|
||
async completeOnboarding() { | ||
await expect(this.welcomeTitle).toBeVisible(); | ||
this.optionallyDismissFwHashCheckError(); | ||
await this.analyticsContinueButton.click(); | ||
await this.onboardingContinueButton.click(); | ||
await this.onboardingViewOnlySkipButton.click(); | ||
await this.viewOnlyTooltipGotItButton.click(); | ||
} | ||
} |
133 changes: 73 additions & 60 deletions
133
packages/suite-desktop-core/e2e/support/pageActions/settingsActions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,85 +1,98 @@ | ||
import { Page } from '@playwright/test'; | ||
import { expect, Locator, Page } from '@playwright/test'; | ||
|
||
import { BackendType, NetworkSymbol } from '@suite-common/wallet-config'; | ||
|
||
import { waitForDataTestSelector } from '../common'; | ||
|
||
const settingSectionsLocators = { | ||
debug: '@settings/debug/github', | ||
general: '@general-settings/language', | ||
device: '@settings/device/backup-recovery-seed', | ||
wallet: '@settings/wallet/network/btc', | ||
} as const; | ||
type Section = keyof typeof settingSectionsLocators; | ||
|
||
export class SettingsActions { | ||
private readonly window: Page; | ||
private readonly TIMES_CLICK_TO_SET_DEBUG_MODE = 5; | ||
readonly settingsHeader: Locator; | ||
readonly debugTabButton: Locator; | ||
readonly applicationTabButton: Locator; | ||
readonly deviceTabButton: Locator; | ||
readonly coinsTabButton: Locator; | ||
readonly earlyAccessJoinButton: Locator; | ||
readonly earlyAccessConfirmCheck: Locator; | ||
readonly earlyAccessConfirmButton: Locator; | ||
readonly earlyAccessSkipButton: Locator; | ||
readonly settingsCloseButton: Locator; | ||
readonly modal: Locator; | ||
//coin Advance settings | ||
readonly coinNetworkButton = (coin: NetworkSymbol) => | ||
this.window.getByTestId(`@settings/wallet/network/${coin}`); | ||
readonly coinAdvanceSettingsButton = (coin: NetworkSymbol) => | ||
this.window.getByTestId(`@settings/wallet/network/${coin}/advance`); | ||
readonly coinBackendSelector: Locator; | ||
readonly coinBackendSelectorOption = (backend: BackendType) => | ||
this.window.getByTestId(`@settings/advance/${backend}`); | ||
readonly coinAddressInput: Locator; | ||
readonly coinAdvanceSettingSaveButton: Locator; | ||
|
||
constructor(window: Page) { | ||
this.window = window; | ||
this.settingsHeader = this.window.getByTestId('@settings/menu/title'); | ||
this.debugTabButton = this.window.getByTestId('@settings/menu/debug'); | ||
this.applicationTabButton = this.window.getByTestId('@settings/menu/general'); | ||
this.deviceTabButton = this.window.getByTestId('@settings/menu/device'); | ||
this.coinsTabButton = this.window.getByTestId('@settings/menu/wallet'); | ||
this.earlyAccessJoinButton = this.window.getByTestId('@settings/early-access-join-button'); | ||
this.earlyAccessConfirmCheck = this.window.getByTestId( | ||
'@settings/early-access-confirm-check', | ||
); | ||
this.earlyAccessConfirmButton = this.window.getByTestId( | ||
'@settings/early-access-confirm-button', | ||
); | ||
this.earlyAccessSkipButton = this.window.getByTestId('@settings/early-access-skip-button'); | ||
this.settingsCloseButton = this.window.getByTestId('@settings/menu/close'); | ||
this.modal = this.window.getByTestId('@modal'); | ||
//coin Advance settings | ||
this.coinBackendSelector = this.window.getByTestId('@settings/advance/select-type/input'); | ||
this.coinAddressInput = this.window.getByTestId('@settings/advance/url'); | ||
this.coinAdvanceSettingSaveButton = this.window.getByTestId( | ||
'@settings/advance/button/save', | ||
); | ||
} | ||
|
||
async toggleDebugModeInSettings() { | ||
const settingsHeader = this.window.getByTestId('@settings/menu/title'); | ||
await settingsHeader.waitFor({ state: 'visible', timeout: 10_000 }); | ||
const timesClickToSetDebugMode = 5; | ||
for (let i = 0; i < timesClickToSetDebugMode; i++) { | ||
await settingsHeader.click(); | ||
await expect(this.settingsHeader).toBeVisible(); | ||
for (let i = 0; i < this.TIMES_CLICK_TO_SET_DEBUG_MODE; i++) { | ||
await this.settingsHeader.click(); | ||
} | ||
await this.window.getByTestId('@settings/menu/debug').waitFor({ state: 'visible' }); | ||
await expect(this.debugTabButton).toBeVisible(); | ||
} | ||
|
||
async goToSettingSection(section: Section) { | ||
await this.window.getByTestId(`@settings/menu/${section}`).click(); | ||
//TODO: #15552 Refactor navigation verification to specific tests and remove this method completely | ||
await this.window | ||
.getByTestId(settingSectionsLocators[section]) | ||
.waitFor({ state: 'visible', timeout: 10_000 }); | ||
} | ||
|
||
async openNetworkSettings(desiredNetwork: NetworkSymbol) { | ||
await this.window.getByTestId(`@settings/wallet/network/${desiredNetwork}`).click(); | ||
const networkSettingsButton = this.window.getByTestId( | ||
`@settings/wallet/network/${desiredNetwork}/advance`, | ||
); | ||
await networkSettingsButton.waitFor({ state: 'visible' }); | ||
await networkSettingsButton.click(); | ||
await waitForDataTestSelector(this.window, '@modal'); | ||
async openCoinAdvanceSettings(coin: NetworkSymbol) { | ||
const isCoinActive = await this.coinNetworkButton(coin).getAttribute('data-active'); | ||
if (isCoinActive === 'false') { | ||
await this.enableCoin(coin); | ||
} | ||
await this.coinNetworkButton(coin).hover(); | ||
await this.coinAdvanceSettingsButton(coin).click(); | ||
await expect(this.modal).toBeVisible(); | ||
} | ||
|
||
async enableCoin(desiredNetwork: NetworkSymbol) { | ||
await this.window.getByTestId(`@settings/wallet/network/${desiredNetwork}`).click(); | ||
async enableCoin(coin: NetworkSymbol) { | ||
await this.coinNetworkButton(coin).click(); | ||
await expect(this.coinNetworkButton(coin)).toHaveAttribute('data-active', 'true'); | ||
} | ||
|
||
async changeNetworkBackend(desiredNetworkBackend: BackendType, backendUrl: string) { | ||
const networkBackendSelector = this.window.getByTestId( | ||
'@settings/advance/select-type/input', | ||
); | ||
await networkBackendSelector.waitFor({ state: 'visible' }); | ||
await networkBackendSelector.click(); | ||
await this.window.getByTestId(`@settings/advance/${desiredNetworkBackend}`).click(); | ||
const electrumAddressInput = this.window.getByTestId('@settings/advance/url'); | ||
await electrumAddressInput.fill(backendUrl); | ||
await this.window.getByTestId('@settings/advance/button/save').click(); | ||
async changeCoinBackend(backend: BackendType, backendUrl: string) { | ||
await this.coinBackendSelector.click(); | ||
await this.coinBackendSelectorOption(backend).click(); | ||
await this.coinAddressInput.fill(backendUrl); | ||
await this.coinAdvanceSettingSaveButton.click(); | ||
} | ||
|
||
async joinEarlyAccessProgram() { | ||
await this.window | ||
.getByTestId('@settings/early-access-join-button') | ||
.scrollIntoViewIfNeeded(); | ||
await this.window.getByTestId('@settings/early-access-join-button').click(); | ||
const eapModal = this.window.getByTestId('@modal'); | ||
await eapModal.waitFor({ state: 'visible' }); | ||
await eapModal.getByTestId('@settings/early-access-confirm-check').click(); | ||
await eapModal.getByTestId('@settings/early-access-confirm-button').click(); | ||
await eapModal.getByTestId('@settings/early-access-skip-button').click(); | ||
} | ||
|
||
async getEarlyAccessButtonText() { | ||
return await this.window.getByTestId('@settings/early-access-join-button').textContent(); | ||
await this.earlyAccessJoinButton.scrollIntoViewIfNeeded(); | ||
await this.earlyAccessJoinButton.click(); | ||
await expect(this.modal).toBeVisible(); | ||
await this.earlyAccessConfirmCheck.click(); | ||
await this.earlyAccessConfirmButton.click(); | ||
await this.earlyAccessSkipButton.click(); | ||
} | ||
|
||
async closeSettings() { | ||
await this.window.getByTestId('@settings/menu/close').click(); | ||
await this.window.getByTestId('@settings/menu/title').waitFor({ state: 'detached' }); | ||
await this.settingsCloseButton.click(); | ||
await this.settingsHeader.waitFor({ state: 'detached' }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.