diff --git a/packages/e2e-utils/src/mocks/google.ts b/packages/e2e-utils/src/mocks/google.ts index 54350f73887..72a49f608c1 100644 --- a/packages/e2e-utils/src/mocks/google.ts +++ b/packages/e2e-utils/src/mocks/google.ts @@ -50,6 +50,25 @@ export class GoogleMock { const app = express(); app.use((req, res, next) => { + if (req.method === 'OPTIONS') { + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); + res.setHeader( + 'Access-Control-Allow-Headers', + 'Content-Type, Authorization, dropbox-api-arg', + ); + res.setHeader('Access-Control-Allow-Credentials', 'true'); + + return res.status(200).end(); + } + + // Handle normal requests + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); + res.setHeader( + 'Access-Control-Allow-Headers', + 'Content-Type, Authorization, dropbox-api-arg', + ); this.requests.push(req.url); if (this.nextResponse.length) { diff --git a/packages/suite-desktop-core/e2e/support/enums/accountLabelId.ts b/packages/suite-desktop-core/e2e/support/enums/accountLabelId.ts new file mode 100644 index 00000000000..7a9f3c62d7a --- /dev/null +++ b/packages/suite-desktop-core/e2e/support/enums/accountLabelId.ts @@ -0,0 +1,7 @@ +export enum AccountLabelId { + BitcoinDefault1 = "m/84'/0'/0'", + BitcoinDefault2 = "m/84'/0'/1'", + BitcoinDefault3 = "m/84'/0'/2'", + BitcoinSegwit1 = "m/49'/0'/0'", + BitcoinSegwit2 = "m/49'/0'/1'", +} diff --git a/packages/suite-desktop-core/e2e/support/metadataProviderMocks.ts b/packages/suite-desktop-core/e2e/support/metadataProviderMocks.ts index 24feaa04d39..93a4a038d74 100644 --- a/packages/suite-desktop-core/e2e/support/metadataProviderMocks.ts +++ b/packages/suite-desktop-core/e2e/support/metadataProviderMocks.ts @@ -54,24 +54,34 @@ const rerouteFetch = ` `; export class MetadataProviderMocks { - private readonly dropBoxMock = new DropboxMock(); - private readonly googleMock = new GoogleMock(); + private providerMock: MetadataProviderMock | undefined; constructor(private readonly page: Page) {} - getMetadataProvider(provider: MetadataProvider): MetadataProviderMock { + @step() + async initializeProviderMocking(provider: MetadataProvider) { switch (provider) { case MetadataProvider.DROPBOX: - return this.dropBoxMock; + this.providerMock = new DropboxMock(); + break; case MetadataProvider.GOOGLE: - return this.googleMock; + this.providerMock = new GoogleMock(); + break; default: throw new Error(`Provider ${provider} not supported`); } - } - @step() - async initializeProviderMocking() { + await this.providerMock.start(); + await this.page.evaluate(rerouteFetch); await this.page.evaluate(stubOpen); } + + @step() + stopProviderMocking() { + if (!this.providerMock) { + throw new Error('Provider mock not initialized'); + } + + this.providerMock.stop(); + } } diff --git a/packages/suite-desktop-core/e2e/tests/metadata/account-metadata.test.ts b/packages/suite-desktop-core/e2e/tests/metadata/account-metadata.test.ts index 7f154eb9861..f7c6850973d 100644 --- a/packages/suite-desktop-core/e2e/tests/metadata/account-metadata.test.ts +++ b/packages/suite-desktop-core/e2e/tests/metadata/account-metadata.test.ts @@ -1,5 +1,6 @@ import { test, expect } from '../../support/fixtures'; -import { MetadataProvider, MetadataProviderMock } from '../../support/metadataProviderMocks'; +import { MetadataProvider } from '../../support/metadataProviderMocks'; +import { AccountLabelId } from '../../support/enums/accountLabelId'; // Metadata is by default disabled, this means, that application does not try to generate master key and connect to cloud. // Hovering over fields that may be labeled shows "add label" button upon which is clicked, Suite initiates metadata flow @@ -8,11 +9,8 @@ test.describe('Account metadata', { tag: ['@group=metadata', '@webOnly'] }, () = emulatorSetupConf: { mnemonic: 'mnemonic_all' }, }); - let provider: MetadataProviderMock; test.beforeEach(async ({ metadataProviderMocks }) => { - metadataProviderMocks.initializeProviderMocking(); - provider = metadataProviderMocks.getMetadataProvider(MetadataProvider.DROPBOX); - await provider.start(); + await metadataProviderMocks.initializeProviderMocking(MetadataProvider.DROPBOX); }); test('dropbox provider', async ({ page, @@ -32,34 +30,34 @@ test.describe('Account metadata', { tag: ['@group=metadata', '@webOnly'] }, () = // Interact with accounts and metadata // Clicking "Bitcoin" label in account menu is not possible, click triggers metadata flow await page.getByTestId('@account-menu/btc/normal/0/label').click(); - await expect(page.getByTestId('@account-menu/btc/normal/0/label')).toContainText('Bitcoin'); + await expect(page.getByTestId('@account-menu/btc/normal/0/label')).toHaveText('Bitcoin #1'); // Metadata flow - await metadataPage.clickAddLabelButton("m/84'/0'/0'"); + await metadataPage.clickAddLabelButton(AccountLabelId.BitcoinDefault1); await metadataPage.passThroughInitMetadata(MetadataProvider.DROPBOX); // Edit label await metadataPage.metadataInput.fill('cool new label'); await page.keyboard.press('Enter'); - await expect(page.getByTestId('@account-menu/btc/normal/0/label')).toContainText( + await expect(page.getByTestId('@account-menu/btc/normal/0/label')).toHaveText( 'cool new label', ); // Submit label changes via button - await metadataPage.editLabel("m/84'/0'/0'", 'even cooler'); - await expect(page.getByTestId('@account-menu/btc/normal/0/label')).toContainText( + await metadataPage.editLabel(AccountLabelId.BitcoinDefault1, 'even cooler'); + await expect(page.getByTestId('@account-menu/btc/normal/0/label')).toHaveText( 'even cooler', ); - await expect(metadataPage.successLabel("m/84'/0'/0'")).toBeVisible(); - await expect(metadataPage.successLabel("m/84'/0'/0'")).not.toBeVisible(); + await expect(metadataPage.successLabel(AccountLabelId.BitcoinDefault1)).toBeVisible(); + await expect(metadataPage.successLabel(AccountLabelId.BitcoinDefault1)).not.toBeVisible(); // Discard changes via escape - await metadataPage.accountLabel("m/84'/0'/0'").click(); - await metadataPage.editLabelButton("m/84'/0'/0'").click(); + await metadataPage.accountLabel(AccountLabelId.BitcoinDefault1).click(); + await metadataPage.editLabelButton(AccountLabelId.BitcoinDefault1).click(); await metadataPage.metadataInput.fill('bcash is true bitcoin'); await page.keyboard.press('Escape'); - await expect(page.getByTestId('@account-menu/btc/normal/0/label')).toContainText( + await expect(page.getByTestId('@account-menu/btc/normal/0/label')).toHaveText( 'even cooler', ); @@ -73,23 +71,23 @@ test.describe('Account metadata', { tag: ['@group=metadata', '@webOnly'] }, () = await searchInput.clear(); // Remove metadata by clearing input - await metadataPage.hoverAccountLabel("m/84'/0'/0'"); - await metadataPage.editLabelButton("m/84'/0'/0'").click(); + await metadataPage.hoverAccountLabel(AccountLabelId.BitcoinDefault1); + await metadataPage.editLabelButton(AccountLabelId.BitcoinDefault1).click(); await metadataPage.metadataInput.clear(); await page.keyboard.press('Enter'); - await expect(page.getByTestId('@account-menu/btc/normal/0/label')).toContainText('Bitcoin'); + await expect(page.getByTestId('@account-menu/btc/normal/0/label')).toHaveText('Bitcoin #1'); // Test switching between accounts await page.getByTestId('@account-menu/segwit').click(); await page.getByTestId('@account-menu/btc/segwit/0').click(); - await metadataPage.addLabel("m/49'/0'/0'", 'typing into one input'); - await expect(metadataPage.successLabel("m/49'/0'/0'")).toBeVisible(); + await metadataPage.addLabel(AccountLabelId.BitcoinSegwit1, 'typing into one input'); + await expect(metadataPage.successLabel(AccountLabelId.BitcoinSegwit1)).toBeVisible(); await page.getByTestId('@account-menu/btc/segwit/1').click(); - await expect(metadataPage.successLabel("m/49'/0'/1'")).not.toBeVisible(); - await expect(metadataPage.successLabel("m/49'/0'/0'")).not.toBeVisible(); + await expect(metadataPage.successLabel(AccountLabelId.BitcoinSegwit2)).not.toBeVisible(); + await expect(metadataPage.successLabel(AccountLabelId.BitcoinSegwit1)).not.toBeVisible(); // Check metadata requests when switching routes await page.getByTestId('@suite/menu/suite-index').click(); @@ -101,12 +99,15 @@ test.describe('Account metadata', { tag: ['@group=metadata', '@webOnly'] }, () = await settingsPage.coins.networkButton('btc').click(); await page.getByTestId('@add-account').click(); await metadataPage.addLabel( - "m/84'/0'/2'", + AccountLabelId.BitcoinDefault3, + 'adding label to a newly added account. does it work?', + ); + await expect(page.getByTestId('@account-menu/btc/normal/2/label')).toHaveText( 'adding label to a newly added account. does it work?', ); }); - test.afterEach(() => { - provider.stop(); + test.afterEach(({ metadataProviderMocks }) => { + metadataProviderMocks.stopProviderMocking(); }); }); diff --git a/packages/suite-desktop-core/e2e/tests/metadata/address-metadata.test.ts b/packages/suite-desktop-core/e2e/tests/metadata/address-metadata.test.ts new file mode 100644 index 00000000000..08c52f2b22a --- /dev/null +++ b/packages/suite-desktop-core/e2e/tests/metadata/address-metadata.test.ts @@ -0,0 +1,49 @@ +import { test, expect } from '../../support/fixtures'; +import { MetadataProvider } from '../../support/metadataProviderMocks'; + +const metadataEl = '@metadata/addressLabel/bc1q7e6qu5smalrpgqrx9k2gnf0hgjyref5p36ru2m'; + +test.describe('Metadata - address labeling', { tag: ['@group=metadata', '@webOnly'] }, () => { + test.use({ + emulatorStartConf: { wipe: true }, + emulatorSetupConf: { mnemonic: 'mnemonic_all' }, + }); + + test.beforeEach(async ({ metadataProviderMocks }) => { + await metadataProviderMocks.initializeProviderMocking(MetadataProvider.GOOGLE); + }); + test('google provider', async ({ page, onboardingPage, metadataPage, dashboardPage }) => { + // Pass through onboarding and device authentication + await onboardingPage.completeOnboarding(); + + // Finish discovery process + // Discovery process completed + await dashboardPage.discoveryShouldFinish(); + await expect(page.getByTestId('@account-menu/btc/normal/0')).toBeVisible(); + + // Interact with accounts and metadata + await page.getByTestId('@account-menu/btc/normal/0').click(); + await page.getByTestId('@wallet/menu/wallet-receive').click(); + await page.getByTestId('@wallet/receive/used-address/show-more').click(); + await page.getByTestId(`${metadataEl}/add-label-button`).click(); + + // Initialize metadata flow + // Metadata provider: google + metadataPage.passThroughInitMetadata(MetadataProvider.GOOGLE); + + await metadataPage.metadataInput.fill('meow address'); + await page.keyboard.press('Enter'); + await expect(page.getByTestId(metadataEl)).toHaveText('meow address'); + + // Edit metadata label + await page.getByTestId(metadataEl).hover(); + await page.getByTestId(`${metadataEl}/edit-label-button`).click(); + await metadataPage.metadataInput.fill('meow meow'); + await page.keyboard.press('Enter'); + await expect(page.getByTestId(metadataEl)).toHaveText('meow meow'); + }); + + test.afterEach(({ metadataProviderMocks }) => { + metadataProviderMocks.stopProviderMocking(); + }); +}); diff --git a/packages/suite-web/e2e/tests/metadata/address-metadata.test.ts b/packages/suite-web/e2e/tests/metadata/address-metadata.test.ts deleted file mode 100644 index 7a131280d84..00000000000 --- a/packages/suite-web/e2e/tests/metadata/address-metadata.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -// @group_metadata -// @retry=2 - -import { rerouteMetadataToMockProvider, stubOpen } from '../../stubs/metadata'; - -const provider = 'google'; - -const metadataEl = '@metadata/addressLabel/bc1q7e6qu5smalrpgqrx9k2gnf0hgjyref5p36ru2m'; - -describe('Metadata - address labeling', () => { - beforeEach(() => { - cy.viewport('macbook-13').resetDb(); - }); - - it(provider, () => { - // prepare test - cy.task('startEmu', { wipe: true }); - cy.task('setupEmu', { mnemonic: 'mnemonic_all' }); - cy.task('startBridge'); - cy.task('metadataStartProvider', provider); - cy.prefixedVisit('/', { - onBeforeLoad: (win: Window) => { - cy.stub(win, 'open').callsFake(stubOpen(win)); - cy.stub(win, 'fetch').callsFake(rerouteMetadataToMockProvider); - }, - }); - - cy.passThroughInitialRun(); - cy.discoveryShouldFinish(); - - cy.getTestElement('@account-menu/btc/normal/0').click(); - cy.getTestElement('@wallet/menu/wallet-receive').click(); - cy.getTestElement('@wallet/receive/used-address/show-more').click(); - cy.getTestElement(`${metadataEl}/add-label-button`).click({ force: true }); - cy.passThroughInitMetadata(provider); - - cy.getTestElement('@metadata/input').type('meoew address{enter}'); - cy.wait(2001); // reasonable here, elements visible only on hover are difficult to wait for in cypress - cy.getTestElement(`${metadataEl}/edit-label-button`).click({ force: true }); - cy.getTestElement('@metadata/input').type(' meoew meow{enter}'); - }); -});