Skip to content

Commit

Permalink
test(connect-popup): e2e for core in popup
Browse files Browse the repository at this point in the history
  • Loading branch information
martykan committed May 14, 2024
1 parent b01a427 commit 2e0180b
Show file tree
Hide file tree
Showing 14 changed files with 123 additions and 19 deletions.
68 changes: 67 additions & 1 deletion .github/workflows/template-connect-popup-test-params.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ on:
type: "boolean"
required: false
default: true
run-core-in-popup:
description: "Flag to indicate whether to run the core-in-popup job"
type: "boolean"
required: false
default: false
build-overview:
description: "Flag to indicate whether to build connect-popup-overview.html"
type: "boolean"
Expand Down Expand Up @@ -68,7 +73,7 @@ jobs:
uses: actions/upload-artifact@v4
if: ${{ inputs.build-overview }}
with:
name: static-overview-${{ inputs.test-name }}-${{ github.run_attempt }}
name: core-in-popup-static-overview-${{ inputs.test-name }}-${{ github.run_attempt }}
path: |
tmp_overview_directory/
Expand Down Expand Up @@ -146,3 +151,64 @@ jobs:
echo "Tests failed"
exit 1
fi
core_in_popup:
name: core_in_popup
runs-on: ubuntu-latest
if: ${{ inputs.run-core-in-popup }}
steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Extract branch name
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
id: extract_branch

- name: Install dependencies
run: |
echo -e "\nenableScripts: false" >> .yarnrc.yml
yarn workspaces focus @trezor/connect-popup
- name: Run connect popup test
env:
URL: https://${{ inputs.DEV_SERVER_HOSTNAME }}/connect/${{ steps.extract_branch.outputs.branch }}/?core-in-popup=true
CORE_IN_POPUP: true
# skip settings page, this url is set at build time anyway
#TREZOR_CONNECT_SRC: https://${{ inputs.DEV_SERVER_HOSTNAME }}/connect/${{ steps.extract_branch.outputs.branch }}/
CI_COMMIT_BRANCH: ${{ steps.extract_branch.outputs.branch }}
CI_JOB_NAME: ${{ inputs.test-name }}-${{ github.run_attempt }}
run: |
./docker/docker-connect-popup-ci.sh ${{ inputs.test-name }}
- name: Prepare static overview
if: ${{ inputs.build-overview }}
run: |
echo "Preparing static overview"
mkdir -p tmp_overview_directory
cp -R ./packages/connect-popup/e2e/screenshots/* tmp_overview_directory/
cp packages/connect-popup/connect-popup-overview.html tmp_overview_directory/connect-popup-overview.html
- name: Upload static overview artifact
uses: actions/upload-artifact@v4
if: ${{ inputs.build-overview }}
with:
name: static-overview-${{ inputs.test-name }}-${{ github.run_attempt }}
path: |
tmp_overview_directory/
- name: Upload artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: core-in-popup-test-artifacts-${{ inputs.test-name }}-${{ github.run_attempt }}-${{ github.run_id }}
path: |
packages/connect-popup/test-results
- name: Check Test Success
run: |
# If there is `test-results` it means it has failed.
if [ -f "packages/connect-popup/test-results" ]; then
echo "Tests failed"
exit 1
fi
3 changes: 3 additions & 0 deletions .github/workflows/test-connect-popup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ jobs:
test-name: methods.test
DEV_SERVER_HOSTNAME: dev.suite.sldev.cz
run-webextension: ${{ github.event_name == 'schedule' }}
run-core-in-popup: true
build-overview: true

popup-close:
Expand All @@ -79,6 +80,7 @@ jobs:
test-name: popup-close.test
DEV_SERVER_HOSTNAME: dev.suite.sldev.cz
run-webextension: true
run-core-in-popup: true

passphrase:
needs: [build-deploy]
Expand All @@ -87,6 +89,7 @@ jobs:
test-name: passphrase.test
DEV_SERVER_HOSTNAME: dev.suite.sldev.cz
run-webextension: true
run-core-in-popup: true

popup-pages:
needs: [build-deploy]
Expand Down
1 change: 1 addition & 0 deletions docker/docker-compose.connect-popup-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ services:
- CI_JOB_NAME=$CI_JOB_NAME
- TEST_FILE=$TEST_FILE
- IS_WEBEXTENSION=$IS_WEBEXTENSION
- CORE_IN_POPUP=$CORE_IN_POPUP
- TREZOR_CONNECT_SRC=$TREZOR_CONNECT_SRC
working_dir: /e2e
command: bash -c "npx playwright install && yarn workspace @trezor/connect-popup test:e2e $TEST_FILE"
Expand Down
1 change: 1 addition & 0 deletions docker/docker-compose.connect-popup-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ services:
- PWDEBUG=console
- TEST_FILE=$TEST_FILE
- IS_WEBEXTENSION=$IS_WEBEXTENSION
- CORE_IN_POPUP=$CORE_IN_POPUP
- TREZOR_CONNECT_SRC=$TREZOR_CONNECT_SRC
working_dir: /trezor-suite
command: bash -c "docker/wait-for-200.sh http://localhost:8088/index.html && yarn workspace @trezor/connect-popup test:e2e $TEST_FILE"
Expand Down
1 change: 1 addition & 0 deletions docker/docker-connect-popup-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export LOCAL_USER_ID
export TEST_FILE=$1
export URL=$URL
export TREZOR_CONNECT_SRC=$TREZOR_CONNECT_SRC
export CORE_IN_POPUP=$CORE_IN_POPUP
export IS_WEBEXTENSION=$IS_WEBEXTENSION

docker compose -f ./docker/docker-compose.connect-popup-ci.yml up --build --abort-on-container-exit
2 changes: 2 additions & 0 deletions docker/docker-connect-popup-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ LOCAL_USER_ID="$(id -u "$USER")"
export LOCAL_USER_ID
export TEST_FILE=$1
export TREZOR_CONNECT_SRC=http://localhost:8088/
export CORE_IN_POPUP=$CORE_IN_POPUP
export IS_WEBEXTENSION=$IS_WEBEXTENSION

docker compose -f ./docker/docker-compose.connect-popup-test.yml up --build --abort-on-container-exit
7 changes: 5 additions & 2 deletions packages/connect-explorer/src/actions/trezorConnectActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,12 @@ export const init =
console.log('using @trezor/connect hosted on: ', window.__TREZOR_CONNECT_SRC);
}

// Get default useCoreInPopup from URL params (?core-in-popup=true)
const urlParams = new URLSearchParams(window.location.search);
const useCoreInPopup = urlParams.get('core-in-popup') === 'true';

const connectOptions = {
// Example with core mode enabled
useCoreInPopup: true,
useCoreInPopup,
transportReconnect: true,
popup: true,
debug: true,
Expand Down
3 changes: 3 additions & 0 deletions packages/connect-popup/e2e/support/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ export const setConnectSettings = async (
connectSrc,
);
}
if (process.env.CORE_IN_POPUP) {
await waitAndClick(explorerPage, ['@checkbox/useCoreInPopup']);
}
await waitAndClick(explorerPage, ['@submit-button']);
};

Expand Down
3 changes: 2 additions & 1 deletion packages/connect-popup/e2e/tests/methods.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ let device = {};
let context: any = null;

const isWebExtension = process.env.IS_WEBEXTENSION === 'true';
const isCoreInPopup = process.env.CORE_IN_POPUP === 'true';

const screenshotEmu = async (path: string) => {
const { response } = await TrezorUserEnvLink.send({
Expand Down Expand Up @@ -133,7 +134,7 @@ filteredFixtures.forEach(f => {
});
await popup.click("button[data-test='@analytics/continue-button']");

if (isWebExtension) {
if (isWebExtension || isCoreInPopup) {
log(f.url, 'waiting for select device');
await popup.waitForSelector('.select-device-list button.list', { state: 'visible' });
await popup.click('.select-device-list button.list');
Expand Down
24 changes: 19 additions & 5 deletions packages/connect-popup/e2e/tests/passphrase.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const url = process.env.URL || 'http://localhost:8088/';
const bridgeVersion = '2.0.31';

const isWebExtension = process.env.IS_WEBEXTENSION === 'true';
const isCoreInPopup = process.env.CORE_IN_POPUP === 'true';
const skipCheck = isWebExtension || isCoreInPopup;
const connectSrc = process.env.TREZOR_CONNECT_SRC;

let context: any = null;
Expand Down Expand Up @@ -102,7 +104,7 @@ test('input passphrase in popup and device accepts it', async () => {
log('clicking on analytics continue button');
await waitAndClick(popup, ['@analytics/continue-button']);

if (isWebExtension) {
if (isWebExtension || isCoreInPopup) {
log('waiting for device list');
await popup.waitForSelector('.select-device-list button.list');
await popup.click('.select-device-list button.list');
Expand Down Expand Up @@ -149,7 +151,7 @@ test('introduce passphrase in popup and device rejects it', async () => {
}
await waitAndClick(popup, ['@analytics/continue-button']);

if (isWebExtension) {
if (isWebExtension || isCoreInPopup) {
log('waiting for device list');
await popup.waitForSelector('.select-device-list button.list');
await popup.click('.select-device-list button.list');
Expand All @@ -174,7 +176,7 @@ test('introduce passphrase in popup and device rejects it', async () => {
});

test('introduce passphrase successfully next time should not ask for it', async () => {
test.skip(isWebExtension, 'test does not apply for webextension');
test.skip(skipCheck, 'test does not apply for webextension');

log(`test: ${test.info().title}`);

Expand Down Expand Up @@ -220,7 +222,7 @@ test('introduce passphrase successfully next time should not ask for it', async
});

test('introduce passphrase successfully reload 3rd party it should ask again for passphrase', async () => {
test.skip(isWebExtension, 'test does not apply for webextension');
test.skip(skipCheck, 'test does not apply for webextension');

log(`test: ${test.info().title}`);

Expand Down Expand Up @@ -270,7 +272,7 @@ test('introduce passphrase successfully reload 3rd party it should ask again for

test('passphrase mismatch', async ({ page }) => {
// This test uses addScriptTag so we cannot run it in web extension.
test.skip(isWebExtension);
test.skip(skipCheck);
log(`test: ${test.info().title}`);

log('start', test.info().title);
Expand Down Expand Up @@ -356,6 +358,18 @@ test('passphrase mismatch', async ({ page }) => {

[popup] = await Promise.all([page.waitForEvent('popup')]);

// Acquire device if not acquired
try {
log('handling if unacquired');
await popup.waitForSelector('.explain.unacquired', {
state: 'visible',
timeout: 10000,
});
await popup.click('.explain.unacquired');
} catch (error) {
// May appear or not
}

log('waiting and click confirm permissions button');
await waitAndClick(popup, ['@permissions/confirm-button', '@export-address/confirm-button']);

Expand Down
19 changes: 13 additions & 6 deletions packages/connect-popup/e2e/tests/popup-close.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {

const url = process.env.URL || 'http://localhost:8088/';
const isWebExtension = process.env.IS_WEBEXTENSION === 'true';
const isCoreInPopup = process.env.CORE_IN_POPUP === 'true';
const skipCheck = isWebExtension || isCoreInPopup;
const connectSrc = process.env.TREZOR_CONNECT_SRC;

const WAIT_AFTER_TEST = 3000; // how long test should wait for more potential trezord requests
Expand Down Expand Up @@ -62,7 +64,7 @@ const setup = async ({ page, context }: { page: Page; context?: BrowserContext }
explorerUrl = contexts.explorerUrl;

const logPage = await browserContext!.newPage();
await logPage.goto(`${url}log.html`);
await logPage.goto(formatUrl(url, 'log.html'));

await setConnectSettings(
explorerPage,
Expand Down Expand Up @@ -100,7 +102,7 @@ const setup = async ({ page, context }: { page: Page; context?: BrowserContext }
log('beforeEach', 'waiting for popup load state');
await popup.waitForLoadState('load');

if (isWebExtension) {
if (isWebExtension || isCoreInPopup) {
log('beforeEach', 'waiting for select device');
await popup.waitForSelector('.select-device-list button.list', { state: 'visible' });
await popup.click('.select-device-list button.list');
Expand Down Expand Up @@ -224,6 +226,11 @@ test('when user cancels permissions in popup it closes automatically', async ({

await popup.waitForLoadState('load');

if (isCoreInPopup) {
await popup.waitForSelector('.select-device-list button.list', { state: 'visible' });
await popup.click('.select-device-list button.list');
}

await popup.waitForSelector('button.confirm', { state: 'visible', timeout: 40000 });
await popup.waitForSelector("button[data-test='@permissions/confirm-button']");
// We are testing that when cancel permissions, popup is closed automatically.
Expand All @@ -234,7 +241,7 @@ test('when user cancels permissions in popup it closes automatically', async ({

test('device dialogue cancelled IN POPUP by user', async ({ page, context }) => {
// TODO: this test should also work with webextension and for some reason it does not work in CI but it works locally.
test.skip(isWebExtension, 'todo: skip for now');
test.skip(skipCheck, 'todo: skip for now');
log(`test: ${test.info().title}`);
await setup({ page, context });

Expand Down Expand Up @@ -276,7 +283,7 @@ test('popup should close and open new one when popup is in error state and user
context,
}) => {
// TODO: this test should also work with webextension and for some reason it does not work in CI but it works locally.
test.skip(isWebExtension, 'todo: skip for now');
test.skip(skipCheck, 'todo: skip for now');

log(`test: ${test.info().title}`);
await setup({ page, context });
Expand Down Expand Up @@ -309,7 +316,7 @@ test('popup should be focused when a call is in progress and user triggers new c
context,
}) => {
// TODO: this test should also work with webextension and for some reason it does not work in CI but it works locally.
test.skip(isWebExtension, 'todo: skip for now');
test.skip(skipCheck, 'todo: skip for now');
log(`test: ${test.info().title}`);
await setup({ page, context });

Expand Down Expand Up @@ -356,7 +363,7 @@ test('popup should be focused when a call is in progress and user triggers new c
test('popup should close when third party is closed', async ({ page, context }) => {
// This test should be skipped in webextension with service-worker, due to the fact that in that case
// that serviceworker is persistent and does not necessarily has to be over if the page that initiated the call is closed.
test.skip(isWebExtension, 'test does not apply for webextension');
test.skip(skipCheck, 'test does not apply for webextension');

log(`test: ${test.info().title}`);
await setup({ page, context });
Expand Down
7 changes: 4 additions & 3 deletions packages/connect-popup/e2e/tests/popup-pages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,11 @@ test('log page should contain logs from shared worker', async ({ page, context }
// Open new tab to go to log.html
const logsPage = await persistentContext.newPage();

log(`go to: ${url}log.html`);
await logsPage.goto(`${url}log.html`);
const logsUrl = `${url.split('?')[0]}log.html`;
log(`go to: ${logsUrl}`);
await logsPage.goto(logsUrl);
await logsPage.waitForLoadState('load');
log(`loaded: ${url}log.html`);
log(`loaded: ${logsUrl}`);

log('waiting for download-button to be visible');
await logsPage.waitForSelector("button[data-test='@log-container/download-button']", {
Expand Down
2 changes: 2 additions & 0 deletions packages/connect-popup/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ const escapeHtml = (payload: any) => {
};

export const handleUIAffectingMessage = (message: CoreEventMessage) => {
// WIP debug
console.log('popup UI message', message.type, message.payload);
switch (message.type) {
case POPUP.METHOD_INFO:
setState({
Expand Down
1 change: 0 additions & 1 deletion packages/connect-web/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const selectMethodImpl =

const TrezorConnect = factory({
init: (settings: Partial<ConnectSettings> = {}) => {
console.log('TrezorConnect.init', settings);
useCoreInPopup = settings?.useCoreInPopup === true;

return selectMethodImpl('init')(settings);
Expand Down

0 comments on commit 2e0180b

Please sign in to comment.