Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(e2e): Migrated e2e tests for metadata providers api errors #16443

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 37 additions & 12 deletions packages/e2e-utils/src/mocks/dropbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export class DropboxMock {
'Content-Type, Authorization, dropbox-api-arg',
);
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Access-Control-Max-Age', '86400');

return res.status(200).end();
}
Expand All @@ -41,11 +42,17 @@ export class DropboxMock {
'Access-Control-Allow-Headers',
'Content-Type, Authorization, dropbox-api-arg',
);
res.setHeader(
'Access-Control-Expose-Headers',
'dropbox-api-result, Content-Type, Authorization',
);
res.setHeader('Access-Control-Allow-Credentials', 'true');

this.requests.push(req.url);

if (this.nextResponse.length) {
const response = this.nextResponse.shift();
console.log('[dropboxMock]', response);
console.log('[mockDropbox]: response', response);
// @ts-expect-error
res.writeHeader(response.status, response.headers);
res.write(JSON.stringify(response!.body));
Expand All @@ -63,7 +70,7 @@ export class DropboxMock {

// https://api.dropboxapi.com/oauth2/token
app.post('/oauth2/token', (req, res) => {
console.log('[dropbox]: token');
console.log('[mockDropbox]: token');
const { grant_type } = req.query;
if (grant_type === 'authorization_code') {
return res.send({
Expand Down Expand Up @@ -167,17 +174,17 @@ export class DropboxMock {
const name = path.replace('/apps/trezor', '');

const file = this.files[name];

if (file) {
// @ts-expect-error
res.writeHeader(200, {
'Content-Type': 'application/octet-stream',
'Dropbox-Api-Result': `{"name": "${name}", "path_lower": "${path}", "path_display": "/Apps/TREZOR/${name}", "id": "id:foo-bar", "client_modified": "2020-10-07T09:52:45Z", "server_modified": "2020-10-07T09:52:45Z", "rev": "foo-bar", "size": 666, "is_downloadable": true, "content_hash": "foo-bar"}`,
'Content-Length': Buffer.byteLength(file),
'Dropbox-Api-Result': `{"name": "${name}", "path_lower": "${path}", "path_display": "/Apps/TREZOR/${name}", "id": "id:foo-bar", "client_modified": "2020-10-07T09:52:45Z", "server_modified": "2020-10-07T09:52:45Z", "rev": "foo-bar", "size": ${Buffer.byteLength(file)}, "is_downloadable": true, "content_hash": "foo-bar"}`,
});

res.write(file, 'binary');
} else {
console.error('[dropboxMock]: no such file found', file);
console.error('[dropboxMock]: no such file found', name);
}

return res.end();
Expand Down Expand Up @@ -209,21 +216,34 @@ export class DropboxMock {

console.log('[mockDropbox]: start');

return new Promise(resolve => {
// @ts-expect-error
this.app!.listen(port, server => {
console.log(`[mockDropbox] listening at http://localhost:${port}`);
return new Promise<void>(resolve => {
const server = this.app!.listen(port, () => {
console.log(`[mockDropbox]: listening at http://localhost:${port}`);
this.running = true;
this.server = server;
resolve(undefined);
resolve();
});
});
}

stop() {
async stop() {
console.log('[mockDropbox]: stop');
if (this.server) {
this.server.close();
await new Promise<void>((resolve, reject) => {
this.server.close((err: Error | undefined) => {
if (err) {
console.error('[mockDropbox]: Error stopping server', err);

return reject(err);
}
console.log('[mockDropbox]: Server stopped successfully');
this.running = false;
this.server = null;
resolve();
});
});
} else {
console.log('[mockDropbox]: Server is not running');
}
}

Expand All @@ -233,4 +253,9 @@ export class DropboxMock {
this.nextResponse = [];
this.requests = [];
}

setFile(name: string, content: Buffer) {
console.log('[mockDropbox]: setFile', name);
this.files[name] = content;
}
}
29 changes: 21 additions & 8 deletions packages/e2e-utils/src/mocks/google.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,21 +195,34 @@ export class GoogleMock {

console.log('[mockGoogleDrive]: start');

return new Promise(resolve => {
// @ts-expect-error
this.app.listen(port, server => {
console.log(`[mockGoogleDrive] listening at http://localhost:${port}`);
return new Promise<void>(resolve => {
const server = this.app!.listen(port, () => {
console.log(`[mockGoogleDrive]: listening at http://localhost:${port}`);
this.running = true;
this.server = server;
resolve(undefined);
resolve();
});
});
}

stop() {
console.log('[mockGoogleDrive]: start');
async stop() {
console.log('[mockGoogleDrive]: stop');
if (this.server) {
this.server.close();
await new Promise<void>((resolve, reject) => {
this.server.close((err: Error | undefined) => {
if (err) {
console.error('[mockGoogleDrive]: Error stopping server', err);

return reject(err);
}
console.log('[mockGoogleDrive]: Server stopped successfully');
this.running = false;
this.server = null;
resolve();
});
});
} else {
console.log('[mockGoogleDrive]: Server is not running');
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Page } from '@playwright/test';

import * as metadataUtils from '@trezor/suite/src/utils/suite/metadata';
import { GoogleMock, DropboxMock } from '@trezor/e2e-utils';

import { step } from '../common';
Expand Down Expand Up @@ -77,11 +78,30 @@ export class MetadataProviderMock {
}

@step()
stop() {
setNextResponse(response: Record<string, any>): void {
if (!this.providerMock) {
throw new Error('Provider mock not initialized');
}

this.providerMock.stop();
this.providerMock.nextResponse.push(response);
}

@step()
async setFileContent(file: string, content: Record<string, any> | string, aesKey: string) {
if (!this.providerMock) {
throw new Error('Provider mock not initialized');
}

const encrypted = await metadataUtils.encrypt(content, aesKey);
this.providerMock.setFile(file, encrypted);
}

@step()
async stop() {
if (!this.providerMock) {
throw new Error('Provider mock not initialized');
}

await this.providerMock.stop();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,18 @@ export class MetadataActions {
}

@step()
async passThroughInitMetadata(provider: MetadataProvider) {
async passThroughInitMetadata(
provider: MetadataProvider,
options?: { skipVerification?: boolean },
) {
await this.devicePrompt.confirmOnDevicePromptIsShown();
await TrezorUserEnvLink.pressYes();
await this.page.getByTestId(`@modal/metadata-provider/${provider}-button`).click();

if (options?.skipVerification) {
return;
}

await expect(this.page.getByTestId('@modal/metadata-provider')).not.toBeVisible({
timeout: 30000,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export class SettingsActions {
readonly languageInputOption = (language: Language) =>
this.page.getByTestId(`@settings/language-select/option/${language}`);
readonly checkSeedButton: Locator;
readonly metadataSwitch: Locator;

constructor(
private readonly page: Page,
Expand Down Expand Up @@ -96,6 +97,7 @@ export class SettingsActions {
this.themeInput = this.page.getByTestId('@theme/color-scheme-select/input');
this.languageInput = this.page.getByTestId('@settings/language-select/input');
this.checkSeedButton = this.page.getByTestId('@settings/device/check-seed-button');
this.metadataSwitch = this.page.getByTestId('@settings/metadata-switch');
}

@step()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ test.describe('Account metadata', { tag: ['@group=metadata', '@webOnly'] }, () =
// Discovery process completed
await dashboardPage.discoveryShouldFinish();

await expect(page.getByTestId('@account-menu/btc/normal/0')).toBeVisible();

// 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();
Expand Down Expand Up @@ -105,7 +103,7 @@ test.describe('Account metadata', { tag: ['@group=metadata', '@webOnly'] }, () =
);
});

test.afterEach(({ metadataProviderMock }) => {
metadataProviderMock.stop();
test.afterEach(async ({ metadataProviderMock }) => {
await metadataProviderMock.stop();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ test.describe('Metadata - address labeling', { tag: ['@group=metadata', '@webOnl
await expect(page.getByTestId(metadataEl)).toHaveText('meow meow');
});

test.afterEach(({ metadataProviderMock }) => {
metadataProviderMock.stop();
test.afterEach(async ({ metadataProviderMock }) => {
await metadataProviderMock.stop();
});
});
Loading
Loading