From c8485e4025f1d46565045da27276208e053ec1bf Mon Sep 17 00:00:00 2001 From: Roma Sosnovsky Date: Wed, 1 Feb 2023 16:54:26 +0200 Subject: [PATCH] issue #4734 Use separate mock api for each test (#4928) * remove unnecessary eslint-disable * choose random port for tests * improve test port setting * add default mock api * separate port for each test * get extension id once * make tests independent * fix extensionDir path * update setMaxListeners * add debug info * more logs * update WKD_API_HOST * update consts * debug * test ContactStore * run all unit tests * run only unit tests * fix unit mock port * run all wkd tests * separate gmail tests * disable gmail * disable gmail * remove acct param * add logging * more logging * new logs * log oauth url * log errors * log current consts * log extension dir * log extension files * update config script * update config script * update config script * check test * run all tests * fix unit tests * use port for send message strategy * fix flaky tests * split standard tests * use browser pool * fix settings tests * fix compose and settings tests * fix for settings tests * fix email parsing * fix setup tests * use custom port for send strategies * fix typo * fix fes mock endpoints * fix mock email parsing * code cleanup * fix mock errors handling * code cleanup * code cleanup * increase concurrency * close mock api on test end * fix mock api close * code cleanup * remove closeMockApi from AvaContext * move closeMockApi to try/finally --- .eslintrc.js | 5 +- conf/tsconfig.test.json | 3 +- extension/chrome/elements/attachment.ts | 6 +- extension/chrome/elements/backup.ts | 3 +- .../pgp-block-attachmens-module.ts | 2 +- .../pgp-block-decrypt-module.ts | 1 - .../pgp-block-error-module.ts | 1 - .../pgp-block-quote-module.ts | 2 +- .../pgp-block-render-module.ts | 9 +- .../pgp-block-signature-module.ts | 1 - .../chrome/settings/setup/setup-create-key.ts | 1 - .../chrome/settings/setup/setup-import-key.ts | 1 - .../setup/setup-key-manager-autogen.ts | 1 - .../settings/setup/setup-recover-key.ts | 1 - .../chrome/settings/setup/setup-render.ts | 1 - extension/js/common/client-configuration.ts | 1 - extension/js/common/core/common.ts | 4 +- .../js/common/core/crypto/pgp/pgp-password.ts | 2 +- extension/js/common/core/expiration-cache.ts | 2 +- extension/js/common/core/msg-block.ts | 2 +- package-lock.json | 539 +++++++++--------- package.json | 24 +- build.sh => scripts/build.sh | 2 +- scripts/config-mock-build.sh | 6 + review-branch.sh => scripts/review-branch.sh | 0 .../add_iframe/add_iframe.js | 5 - .../add_iframe/iframe.htm | 6 - .../add_iframe/manifest.json | 10 - .../ext-frame-online.js | 25 - test/source/browser/browser-handle.ts | 24 +- test/source/browser/browser-pool.ts | 48 +- test/source/browser/controllable.ts | 30 +- test/source/browser/test-urls.ts | 25 +- test/source/buf.ts | 24 +- test/source/mock.ts | 14 - test/source/mock/all-apis-mock.ts | 2 +- test/source/mock/backend/backend-data.ts | 45 +- .../mock/fes/customer-url-fes-endpoints.ts | 114 ++-- .../mock/fes/shared-tenant-fes-endpoints.ts | 21 +- test/source/mock/google/google-data.ts | 32 +- test/source/mock/google/google-endpoints.ts | 19 +- .../strategies/send-message-strategy.ts | 40 +- .../mock/google/strategies/strategy-base.ts | 4 +- .../mock/key-manager/key-manager-endpoints.ts | 5 +- test/source/mock/lib/api.ts | 10 +- test/source/mock/lib/mock-util.ts | 2 + test/source/mock/lib/oauth.ts | 5 +- test/source/test.ts | 163 +++--- test/source/tests/compose.ts | 384 ++++++------- test/source/tests/decrypt.ts | 181 +++--- test/source/tests/elements.ts | 12 +- test/source/tests/flaky.ts | 62 +- test/source/tests/gmail.ts | 51 +- .../tests/page-recipe/abstract-page-recipe.ts | 3 +- .../tests/page-recipe/inbox-page-recipe.ts | 7 +- .../tests/page-recipe/oauth-page-recipe.ts | 2 +- .../tests/page-recipe/settings-page-recipe.ts | 6 +- test/source/tests/settings.ts | 260 ++++----- test/source/tests/setup.ts | 216 +++---- test/source/tests/tooling/browser-recipe.ts | 12 +- test/source/tests/tooling/index.ts | 7 +- test/source/tests/unit-browser.ts | 21 +- test/source/tests/unit-node.ts | 134 ++--- test/source/util/index.ts | 5 +- 64 files changed, 1269 insertions(+), 1387 deletions(-) rename build.sh => scripts/build.sh (98%) create mode 100644 scripts/config-mock-build.sh rename review-branch.sh => scripts/review-branch.sh (100%) delete mode 100644 test/debug/puppeteer_cannot_access_iframes/add_iframe/add_iframe.js delete mode 100644 test/debug/puppeteer_cannot_access_iframes/add_iframe/iframe.htm delete mode 100644 test/debug/puppeteer_cannot_access_iframes/add_iframe/manifest.json delete mode 100644 test/debug/puppeteer_cannot_access_iframes/ext-frame-online.js delete mode 100644 test/source/mock.ts diff --git a/.eslintrc.js b/.eslintrc.js index 60a493795f2..e0ed6475d1f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -70,7 +70,6 @@ module.exports = { leadingUnderscore: 'allow', }, ], - '@typescript-eslint/no-empty-function': 'error', '@typescript-eslint/no-empty-interface': 'off', '@typescript-eslint/no-explicit-any': ['warn'], '@typescript-eslint/no-floating-promises': 'error', @@ -111,14 +110,13 @@ module.exports = { 'no-control-regex': 0, 'no-debugger': 'error', 'no-empty': 'error', - 'no-empty-function': 'error', 'no-empty-pattern': 0, 'no-eval': 'error', 'no-fallthrough': 0, 'no-invalid-this': 'off', 'no-new-wrappers': 'error', 'no-null/no-null': 'error', - 'no-only-tests/no-only-tests': ['error', { block: ['ava.default'] }], + 'no-only-tests/no-only-tests': ['error'], 'no-prototype-builtins': 0, 'no-shadow': 'off', 'no-throw-literal': 'error', @@ -128,7 +126,6 @@ module.exports = { 'no-unsafe-finally': 'error', 'no-unused-expressions': 'off', 'no-unused-labels': 'error', - 'no-unused-vars': 0, 'no-use-before-define': 'off', 'no-useless-escape': 0, 'no-var': 'error', diff --git a/conf/tsconfig.test.json b/conf/tsconfig.test.json index a56c5bc734e..0c35bd97ab5 100644 --- a/conf/tsconfig.test.json +++ b/conf/tsconfig.test.json @@ -17,7 +17,6 @@ "../test/source/test.ts", "../test/source/patterns.ts", "../test/source/async-stack.ts", - "../test/source/buf.ts", - "../test/source/mock.ts" + "../test/source/buf.ts" ] } diff --git a/extension/chrome/elements/attachment.ts b/extension/chrome/elements/attachment.ts index c9749da364d..9d0cb815f82 100644 --- a/extension/chrome/elements/attachment.ts +++ b/extension/chrome/elements/attachment.ts @@ -103,8 +103,7 @@ export class AttachmentDownloadView extends View { $('img#file-format').attr('src', this.getFileIconSrc()); if (!this.size && this.url) { // download url of a file that has an unknown size - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this.getUrlFileSize(this.url!) + this.getUrlFileSize(this.url) .then(fileSize => { if (typeof fileSize !== 'undefined') { this.size = fileSize; @@ -213,8 +212,7 @@ export class AttachmentDownloadView extends View { console.info('trying to figure out figetUrlFileSizee size'); if (url.indexOf('docs.googleusercontent.getUrlFileSizeom/docs/securesc') !== -1) { try { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const googleDriveFileId = url.split('/').pop()!.split('?').shift(); // try and catch any errors below if structure is not as expected + const googleDriveFileId = url.split('/').pop()?.split('?').shift(); // try and catch any errors below if structure is not as expected url = googleDriveFileId ? `https://drive.google.com/uc?export=download&id=${googleDriveFileId}` : url; // attempt to get length headers from Google Drive file if available } catch (e) { // leave url as is diff --git a/extension/chrome/elements/backup.ts b/extension/chrome/elements/backup.ts index 230ed04b353..78405558c18 100644 --- a/extension/chrome/elements/backup.ts +++ b/extension/chrome/elements/backup.ts @@ -72,8 +72,7 @@ View.run( }; private sendResizeMsg = () => { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const desiredHeight = $('#backup_block').height()!; + const desiredHeight = $('#backup_block').height(); BrowserMsg.send.setCss(this.parentTabId, { selector: `iframe#${this.frameId}`, css: { height: `${desiredHeight}px` }, diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-attachmens-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-attachmens-module.ts index f449c9c6421..e0b0b37a173 100644 --- a/extension/chrome/elements/pgp_block_modules/pgp-block-attachmens-module.ts +++ b/extension/chrome/elements/pgp_block_modules/pgp-block-attachmens-module.ts @@ -17,7 +17,7 @@ declare const filesize: { filesize: Function }; // eslint-disable-line @typescri export class PgpBlockViewAttachmentsModule { public includedAttachments: Attachment[] = []; - public constructor(private view: PgpBlockView) {} // eslint-disable-line no-empty-function + public constructor(private view: PgpBlockView) {} public renderInnerAttachments = (attachments: Attachment[], isEncrypted: boolean) => { Xss.sanitizeAppend('#pgp_block', '
'); diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-decrypt-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-decrypt-module.ts index a85e4d0e8d2..67a2096644c 100644 --- a/extension/chrome/elements/pgp_block_modules/pgp-block-decrypt-module.ts +++ b/extension/chrome/elements/pgp_block_modules/pgp-block-decrypt-module.ts @@ -18,7 +18,6 @@ export class PgpBlockViewDecryptModule { private msgFetchedFromApi: false | GmailResponseFormat = false; private isPwdMsgBasedOnMsgSnippet: boolean | undefined; - // eslint-disable-next-line no-empty-function public constructor(private view: PgpBlockView) {} public initialize = async (verificationPubs: string[], forcePullMsgFromApi: boolean) => { diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-error-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-error-module.ts index ed0d4330987..56908bbbfd0 100644 --- a/extension/chrome/elements/pgp_block_modules/pgp-block-error-module.ts +++ b/extension/chrome/elements/pgp_block_modules/pgp-block-error-module.ts @@ -16,7 +16,6 @@ import { Str } from '../../../js/common/core/common.js'; export class PgpBlockViewErrorModule { private debugId = Str.sloppyRandom(); - // eslint-disable-next-line no-empty-function public constructor(private view: PgpBlockView) {} public renderErr = async (errBoxContent: string, renderRawMsg: string | undefined, errMsg?: string) => { diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-quote-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-quote-module.ts index 3d0e02db33d..f3f83e1e9e9 100644 --- a/extension/chrome/elements/pgp_block_modules/pgp-block-quote-module.ts +++ b/extension/chrome/elements/pgp_block_modules/pgp-block-quote-module.ts @@ -7,7 +7,7 @@ import { Str } from '../../../js/common/core/common.js'; import { Xss } from '../../../js/common/platform/xss.js'; export class PgpBlockViewQuoteModule { - public constructor(private view: PgpBlockView) {} // eslint-disable-line no-empty-function + public constructor(private view: PgpBlockView) {} public separateQuotedContentAndRenderText = async (decryptedContent: string, isHtml: boolean) => { if (isHtml) { diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-render-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-render-module.ts index 562ef865ed9..b4c1739f0df 100644 --- a/extension/chrome/elements/pgp_block_modules/pgp-block-render-module.ts +++ b/extension/chrome/elements/pgp_block_modules/pgp-block-render-module.ts @@ -23,7 +23,6 @@ export class PgpBlockViewRenderModule { private heightHist: number[] = []; private printMailInfoHtml!: string; - // eslint-disable-next-line no-empty-function public constructor(private view: PgpBlockView) {} public initPrintView = async () => { @@ -133,14 +132,12 @@ export class PgpBlockViewRenderModule { `; - /* eslint-disable @typescript-eslint/no-non-null-assertion */ - w!.document.write(html); + w?.document.write(html); // Give some time for above dom to load in print dialog // https://stackoverflow.com/questions/31725373/google-chrome-not-showing-image-in-print-preview await Ui.time.sleep(250); - w!.window.print(); - w!.document.close(); - /* eslint-enable @typescript-eslint/no-non-null-assertion */ + w?.window.print(); + w?.document.close(); }; public renderText = (text: string) => { diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-signature-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-signature-module.ts index 70e6bc34fb8..65b10bc4965 100644 --- a/extension/chrome/elements/pgp_block_modules/pgp-block-signature-module.ts +++ b/extension/chrome/elements/pgp_block_modules/pgp-block-signature-module.ts @@ -11,7 +11,6 @@ import { Value } from '../../../js/common/core/common.js'; import { BrowserMsg } from '../../../js/common/browser/browser-msg.js'; export class PgpBlockViewSignatureModule { - // eslint-disable-next-line no-empty-function public constructor(private view: PgpBlockView) {} public renderPgpSignatureCheckResult = async ( diff --git a/extension/chrome/settings/setup/setup-create-key.ts b/extension/chrome/settings/setup/setup-create-key.ts index 15ad0b79a27..884ae45a1a3 100644 --- a/extension/chrome/settings/setup/setup-create-key.ts +++ b/extension/chrome/settings/setup/setup-create-key.ts @@ -13,7 +13,6 @@ import { OpenPGPKey } from '../../../js/common/core/crypto/pgp/openpgp-key.js'; import { saveKeysAndPassPhrase } from '../../../js/common/helpers.js'; export class SetupCreateKeyModule { - // eslint-disable-next-line no-empty-function public constructor(private view: SetupView) {} public actionCreateKeyHandler = async () => { diff --git a/extension/chrome/settings/setup/setup-import-key.ts b/extension/chrome/settings/setup/setup-import-key.ts index 79ee0f608bd..cca3d9d5df0 100644 --- a/extension/chrome/settings/setup/setup-import-key.ts +++ b/extension/chrome/settings/setup/setup-import-key.ts @@ -14,7 +14,6 @@ import { Lang } from '../../../js/common/lang.js'; import { saveKeysAndPassPhrase } from '../../../js/common/helpers.js'; export class SetupImportKeyModule { - // eslint-disable-next-line no-empty-function public constructor(private view: SetupView) {} public actionImportPrivateKeyHandle = async (button: HTMLElement) => { diff --git a/extension/chrome/settings/setup/setup-key-manager-autogen.ts b/extension/chrome/settings/setup/setup-key-manager-autogen.ts index 609a05e64ee..35aa342518e 100644 --- a/extension/chrome/settings/setup/setup-key-manager-autogen.ts +++ b/extension/chrome/settings/setup/setup-key-manager-autogen.ts @@ -16,7 +16,6 @@ import { processAndStoreKeysFromEkmLocally, saveKeysAndPassPhrase } from '../../ import { Xss } from '../../../js/common/platform/xss.js'; export class SetupWithEmailKeyManagerModule { - // eslint-disable-next-line no-empty-function public constructor(private view: SetupView) {} public continueEkmSetupHandler = async () => { diff --git a/extension/chrome/settings/setup/setup-recover-key.ts b/extension/chrome/settings/setup/setup-recover-key.ts index d98ef5ae47c..6468af2b915 100644 --- a/extension/chrome/settings/setup/setup-recover-key.ts +++ b/extension/chrome/settings/setup/setup-recover-key.ts @@ -15,7 +15,6 @@ import { KeyStore } from '../../../js/common/platform/store/key-store.js'; import { saveKeysAndPassPhrase } from '../../../js/common/helpers.js'; export class SetupRecoverKeyModule { - // eslint-disable-next-line no-empty-function public constructor(private view: SetupView) {} public actionRecoverAccountHandler = async () => { diff --git a/extension/chrome/settings/setup/setup-render.ts b/extension/chrome/settings/setup/setup-render.ts index 0f3611f6baf..8326f3b6370 100644 --- a/extension/chrome/settings/setup/setup-render.ts +++ b/extension/chrome/settings/setup/setup-render.ts @@ -16,7 +16,6 @@ import { KeyImportUi } from '../../../js/common/ui/key-import-ui.js'; export class SetupRenderModule { public readonly emailDomainsToSkip = ['yahoo', 'live', 'outlook']; - // eslint-disable-next-line no-empty-function public constructor(private view: SetupView) {} public renderInitial = async (): Promise => { diff --git a/extension/js/common/client-configuration.ts b/extension/js/common/client-configuration.ts index ab415bdeddb..5f1174aed9d 100644 --- a/extension/js/common/client-configuration.ts +++ b/extension/js/common/client-configuration.ts @@ -49,7 +49,6 @@ export class ClientConfigurationError extends UnreportableError { * These either enforce, alter or forbid various behavior to fit customer needs */ export class ClientConfiguration { - // eslint-disable-next-line no-empty-function protected constructor(private clientConfigurationJson: ClientConfigurationJson, public domainName: string) {} public static newInstance = async (acctEmail: string): Promise => { diff --git a/extension/js/common/core/common.ts b/extension/js/common/core/common.ts index 955b30ceda0..ef98bcc5aa2 100644 --- a/extension/js/common/core/common.ts +++ b/extension/js/common/core/common.ts @@ -23,11 +23,11 @@ export class Str { let name: string | undefined; if (full.includes('<') && full.includes('>')) { email = full - .substr(full.indexOf('<') + 1, full.indexOf('>') - full.indexOf('<') - 1) + .substring(full.indexOf('<') + 1, full.indexOf('>')) .replace(/["']/g, '') .trim() .toLowerCase(); - name = full.substr(0, full.indexOf('<')).replace(/["']/g, '').trim(); + name = full.substring(0, full.indexOf('<')).replace(/["']/g, '').trim(); } else { email = full.replace(/["']/g, '').trim().toLowerCase(); } diff --git a/extension/js/common/core/crypto/pgp/pgp-password.ts b/extension/js/common/core/crypto/pgp/pgp-password.ts index 9ba5188bff2..8847423141d 100644 --- a/extension/js/common/core/crypto/pgp/pgp-password.ts +++ b/extension/js/common/core/crypto/pgp/pgp-password.ts @@ -111,7 +111,7 @@ export class PgpPwd { .toUpperCase() .replace(/[^A-Z0-9]|0|O|1/g, '') .replace(/(.{4})/g, '$1-') - .substr(0, 19); + .substring(0, 19); }; private static readableCrackTime = (totalSeconds: number) => { diff --git a/extension/js/common/core/expiration-cache.ts b/extension/js/common/core/expiration-cache.ts index 1062abe8dcd..0bf762d859c 100644 --- a/extension/js/common/core/expiration-cache.ts +++ b/extension/js/common/core/expiration-cache.ts @@ -6,7 +6,7 @@ export class ExpirationCache { private cache: { [key: string]: { value: string; expiration: number } } = {}; - // eslint-disable-next-line @typescript-eslint/naming-convention, no-empty-function + // eslint-disable-next-line @typescript-eslint/naming-convention public constructor(public EXPIRATION_TICKS: number) {} public set = (key: string, value?: string, expiration?: number) => { diff --git a/extension/js/common/core/msg-block.ts b/extension/js/common/core/msg-block.ts index 3eeb1934659..7a5a2057475 100644 --- a/extension/js/common/core/msg-block.ts +++ b/extension/js/common/core/msg-block.ts @@ -32,7 +32,7 @@ export class MsgBlock { public attachmentMeta?: AttachmentMeta, // only in plainAttachment, encryptedAttachment, decryptedAttachment, encryptedAttachmentLink (not sure if always) public decryptErr?: DecryptError, // only in decryptErr block, always public verifyRes?: VerifyRes - ) {} // eslint-disable-line no-empty-function + ) {} public static fromContent = (type: MsgBlockType, content: string | Buf, missingEnd = false): MsgBlock => { return new MsgBlock(type, content, !missingEnd); diff --git a/package-lock.json b/package-lock.json index e99c78ff8e4..d0d13546022 100644 --- a/package-lock.json +++ b/package-lock.json @@ -172,19 +172,19 @@ } }, "node_modules/@csstools/selector-specificity": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", - "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.1.1.tgz", + "integrity": "sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw==", "dev": true, "engines": { - "node": "^12 || ^14 || >=16" + "node": "^14 || ^16 || >=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.2", + "postcss": "^8.4", "postcss-selector-parser": "^6.0.10" } }, @@ -585,15 +585,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.2.tgz", - "integrity": "sha512-sR0Gja9Ky1teIq4qJOl0nC+Tk64/uYdX+mi+5iB//MH8gwyx8e3SOyhEzeLZEFEEfCaLf8KJq+Bd/6je1t+CAg==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.50.0.tgz", + "integrity": "sha512-vwksQWSFZiUhgq3Kv7o1Jcj0DUNylwnIlGvKvLLYsq8pAWha6/WCnXUeaSoNNha/K7QSf2+jvmkxggC1u3pIwQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/type-utils": "5.48.2", - "@typescript-eslint/utils": "5.48.2", + "@typescript-eslint/scope-manager": "5.50.0", + "@typescript-eslint/type-utils": "5.50.0", + "@typescript-eslint/utils": "5.50.0", "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", @@ -617,62 +618,15 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.2.tgz", - "integrity": "sha512-zEUFfonQid5KRDKoI3O+uP1GnrFd4tIHlvs+sTJXiWuypUWMuDaottkJuR612wQfOkjYbsaskSIURV9xo4f+Fw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/visitor-keys": "5.48.2" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.2.tgz", - "integrity": "sha512-hE7dA77xxu7ByBc6KCzikgfRyBCTst6dZQpwaTy25iMYOnbNljDT4hjhrGEJJ0QoMjrfqrx+j1l1B9/LtKeuqA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.2.tgz", - "integrity": "sha512-z9njZLSkwmjFWUelGEwEbdf4NwKvfHxvGC0OcGN1Hp/XNDIcJ7D5DpPNPv6x6/mFvc1tQHsaWmpD/a4gOvvCJQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.2", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.49.0.tgz", - "integrity": "sha512-veDlZN9mUhGqU31Qiv2qEp+XrJj5fgZpJ8PW30sHU+j/8/e5ruAhLaVDAeznS7A7i4ucb/s8IozpDtt9NqCkZg==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.50.0.tgz", + "integrity": "sha512-KCcSyNaogUDftK2G9RXfQyOCt51uB5yqC6pkUYqhYh8Kgt+DwR5M0EwEAxGPy/+DH6hnmKeGsNhiZRQxjH71uQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.49.0", - "@typescript-eslint/types": "5.49.0", - "@typescript-eslint/typescript-estree": "5.49.0", + "@typescript-eslint/scope-manager": "5.50.0", + "@typescript-eslint/types": "5.50.0", + "@typescript-eslint/typescript-estree": "5.50.0", "debug": "^4.3.4" }, "engines": { @@ -692,13 +646,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.49.0.tgz", - "integrity": "sha512-clpROBOiMIzpbWNxCe1xDK14uPZh35u4QaZO1GddilEzoCLAEz4szb51rBpdgurs5k2YzPtJeTEN3qVbG+LRUQ==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.50.0.tgz", + "integrity": "sha512-rt03kaX+iZrhssaT974BCmoUikYtZI24Vp/kwTSy841XhiYShlqoshRFDvN1FKKvU2S3gK+kcBW1EA7kNUrogg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.49.0", - "@typescript-eslint/visitor-keys": "5.49.0" + "@typescript-eslint/types": "5.50.0", + "@typescript-eslint/visitor-keys": "5.50.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -709,13 +663,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.2.tgz", - "integrity": "sha512-QVWx7J5sPMRiOMJp5dYshPxABRoZV1xbRirqSk8yuIIsu0nvMTZesKErEA3Oix1k+uvsk8Cs8TGJ6kQ0ndAcew==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.50.0.tgz", + "integrity": "sha512-dcnXfZ6OGrNCO7E5UY/i0ktHb7Yx1fV6fnQGGrlnfDhilcs6n19eIRcvLBqx6OQkrPaFlDPk3OJ0WlzQfrV0bQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.48.2", - "@typescript-eslint/utils": "5.48.2", + "@typescript-eslint/typescript-estree": "5.50.0", + "@typescript-eslint/utils": "5.50.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -735,67 +689,10 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.2.tgz", - "integrity": "sha512-hE7dA77xxu7ByBc6KCzikgfRyBCTst6dZQpwaTy25iMYOnbNljDT4hjhrGEJJ0QoMjrfqrx+j1l1B9/LtKeuqA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.2.tgz", - "integrity": "sha512-bibvD3z6ilnoVxUBFEgkO0k0aFvUc4Cttt0dAreEr+nrAHhWzkO83PEVVuieK3DqcgL6VAK5dkzK8XUVja5Zcg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/visitor-keys": "5.48.2", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.2.tgz", - "integrity": "sha512-z9njZLSkwmjFWUelGEwEbdf4NwKvfHxvGC0OcGN1Hp/XNDIcJ7D5DpPNPv6x6/mFvc1tQHsaWmpD/a4gOvvCJQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.2", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/types": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.49.0.tgz", - "integrity": "sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.50.0.tgz", + "integrity": "sha512-atruOuJpir4OtyNdKahiHZobPKFvZnBnfDiyEaBf6d9vy9visE7gDjlmhl+y29uxZ2ZDgvXijcungGFjGGex7w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -806,13 +703,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.49.0.tgz", - "integrity": "sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.50.0.tgz", + "integrity": "sha512-Gq4zapso+OtIZlv8YNAStFtT6d05zyVCK7Fx3h5inlLBx2hWuc/0465C2mg/EQDDU2LKe52+/jN4f0g9bd+kow==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.49.0", - "@typescript-eslint/visitor-keys": "5.49.0", + "@typescript-eslint/types": "5.50.0", + "@typescript-eslint/visitor-keys": "5.50.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -833,16 +730,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.2.tgz", - "integrity": "sha512-2h18c0d7jgkw6tdKTlNaM7wyopbLRBiit8oAxoP89YnuBOzCZ8g8aBCaCqq7h208qUTroL7Whgzam7UY3HVLow==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.50.0.tgz", + "integrity": "sha512-v/AnUFImmh8G4PH0NDkf6wA8hujNNcrwtecqW4vtQ1UOSNBaZl49zP1SHoZ/06e+UiwzHpgb5zP5+hwlYYWYAw==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/typescript-estree": "5.48.2", + "@typescript-eslint/scope-manager": "5.50.0", + "@typescript-eslint/types": "5.50.0", + "@typescript-eslint/typescript-estree": "5.50.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -858,87 +755,13 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.2.tgz", - "integrity": "sha512-zEUFfonQid5KRDKoI3O+uP1GnrFd4tIHlvs+sTJXiWuypUWMuDaottkJuR612wQfOkjYbsaskSIURV9xo4f+Fw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/visitor-keys": "5.48.2" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.2.tgz", - "integrity": "sha512-hE7dA77xxu7ByBc6KCzikgfRyBCTst6dZQpwaTy25iMYOnbNljDT4hjhrGEJJ0QoMjrfqrx+j1l1B9/LtKeuqA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.2.tgz", - "integrity": "sha512-bibvD3z6ilnoVxUBFEgkO0k0aFvUc4Cttt0dAreEr+nrAHhWzkO83PEVVuieK3DqcgL6VAK5dkzK8XUVja5Zcg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/visitor-keys": "5.48.2", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.2.tgz", - "integrity": "sha512-z9njZLSkwmjFWUelGEwEbdf4NwKvfHxvGC0OcGN1Hp/XNDIcJ7D5DpPNPv6x6/mFvc1tQHsaWmpD/a4gOvvCJQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.2", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz", - "integrity": "sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.50.0.tgz", + "integrity": "sha512-cdMeD9HGu6EXIeGOh2yVW6oGf9wq8asBgZx7nsR/D36gTfQ0odE5kcRYe5M81vjEFAcPeugXrHg78Imu55F6gg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.49.0", + "@typescript-eslint/types": "5.50.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -969,9 +792,9 @@ } }, "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1060,6 +883,15 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/addons-linter/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/addons-linter/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -1118,6 +950,115 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/addons-linter/node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/addons-linter/node_modules/eslint": { + "version": "8.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz", + "integrity": "sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/addons-linter/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/addons-linter/node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/addons-linter/node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/addons-linter/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/addons-linter/node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -1137,13 +1078,19 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/addons-linter/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "node_modules/addons-linter/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } }, - "node_modules/addons-linter/node_modules/minimatch": { + "node_modules/addons-linter/node_modules/glob/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", @@ -1155,6 +1102,33 @@ "node": ">=10" } }, + "node_modules/addons-linter/node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/addons-linter/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/addons-linter/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/addons-moz-compare": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/addons-moz-compare/-/addons-moz-compare-1.3.0.tgz", @@ -1867,9 +1841,9 @@ } }, "node_modules/boxen/node_modules/wrap-ansi": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.0.1.tgz", - "integrity": "sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "dependencies": { "ansi-styles": "^6.1.0", @@ -2833,9 +2807,9 @@ } }, "node_modules/data-uri-to-buffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", - "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "dev": true, "engines": { "node": ">= 12" @@ -2966,9 +2940,9 @@ } }, "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz", + "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", "dev": true, "engines": { "node": ">=0.10.0" @@ -3436,9 +3410,9 @@ } }, "node_modules/eslint": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz", - "integrity": "sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.33.0.tgz", + "integrity": "sha512-WjOpFQgKK8VrCnAtl8We0SUOy/oVZ5NHykyMiagV1M9r8IFpIJX7DduK6n1mpfhlG7T1NLWm2SuD8QB7KFySaA==", "dev": true, "dependencies": { "@eslint/eslintrc": "^1.4.1", @@ -3618,9 +3592,9 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "39.6.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.6.4.tgz", - "integrity": "sha512-fskvdLCfwmPjHb6e+xNGDtGgbF8X7cDwMtVLAP2WwSf9Htrx68OAx31BESBM1FAwsN2HTQyYQq7m4aW4Q4Nlag==", + "version": "39.7.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.7.5.tgz", + "integrity": "sha512-6L90P0AnZcE4ra7nocolp9vTjgVr2wEZ7jPnEA/X30XAoQPk+wvnaq61n164Tf7Fg4QPpJtRSCPpApOsfWDdNA==", "dev": true, "dependencies": { "@es-joy/jsdoccomment": "~0.36.1", @@ -4644,9 +4618,9 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "dev": true, "dependencies": { "function-bind": "^1.1.1", @@ -4795,9 +4769,9 @@ } }, "node_modules/globals": { - "version": "13.19.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", - "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -5234,9 +5208,9 @@ } }, "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true }, "node_modules/http-signature": { @@ -5482,9 +5456,9 @@ } }, "node_modules/irregular-plurals": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.3.0.tgz", - "integrity": "sha512-MVBLKUTangM3EfRPFROhmWQQKRDsrgI83J8GS3jXy+OwYqiR2/aoWndYQ5416jLE3uaGgLH7ncme3X9y09gZ3g==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.4.0.tgz", + "integrity": "sha512-YXxECO/W6N9aMBVKMKKZ8TXESgq7EFrp3emCGGUcrYY1cgJIeZjoB75MTu8qi+NAKntS9NwPU8VdcQ3r6E6aWQ==", "dev": true, "engines": { "node": ">=8" @@ -6002,9 +5976,9 @@ "integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg==" }, "node_modules/js-sdsl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", - "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", "dev": true, "funding": { "type": "opencollective", @@ -6021,9 +5995,9 @@ } }, "node_modules/js-tokens": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.0.tgz", - "integrity": "sha512-PC7MzqInq9OqKyTXfIvQNcjMkODJYC8A17kAaQgeW79yfhqTWSOfjHYQ2mDDcwJ96Iibtwkfh0C7R/OvqPlgVA==" + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.1.tgz", + "integrity": "sha512-3AGrZT6tuMm1ZWWn9mLXh7XMfi2YtiLNPALCVxBCiUVq0LD1OQMxV/AdS/s7rLJU5o9i/jBZw/N4vXXL5dm29A==" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -6431,9 +6405,9 @@ } }, "node_modules/listr2": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.6.tgz", - "integrity": "sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.7.tgz", + "integrity": "sha512-MD+qXHPmtivrHIDRwPYdfNkrzqDiuaKU/rfBcec3WMyMF3xylQj3jMq344OtvQxz7zaCFViRAeqlr2AFhPvXHw==", "dev": true, "dependencies": { "cli-truncate": "^2.1.0", @@ -6441,7 +6415,7 @@ "log-update": "^4.0.0", "p-map": "^4.0.0", "rfdc": "^1.3.0", - "rxjs": "^7.5.7", + "rxjs": "^7.8.0", "through": "^2.3.8", "wrap-ansi": "^7.0.0" }, @@ -7153,14 +7127,11 @@ } }, "node_modules/minipass": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.0.tgz", - "integrity": "sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.1.tgz", + "integrity": "sha512-V9esFpNbK0arbN3fm2sxDKqMYgIp7XtVdE4Esj+PE4Qaaxdg1wIw48ITQIOn1sc8xXSmUviVL3cyjMqPlrVkiA==", "dev": true, "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, "engines": { "node": ">=8" } @@ -7602,9 +7573,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8602,9 +8573,9 @@ } }, "node_modules/punycode": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz", - "integrity": "sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, "engines": { "node": ">=6" @@ -10563,9 +10534,9 @@ } }, "node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true }, "node_modules/tsutils": { diff --git a/package.json b/package.json index 7b88da3efe3..dbfcd23f676 100644 --- a/package.json +++ b/package.json @@ -59,9 +59,9 @@ "zxcvbn": "4.4.2" }, "scripts": { - "build": "./build.sh", - "build-incremental": "./build.sh --incremental", - "build-assets-only": "./build.sh --assets-only", + "build": "./scripts/build.sh", + "build-incremental": "./scripts/build.sh --incremental", + "build-assets-only": "./scripts/build.sh --assets-only", "pretest": "npm run build --silent && cd conf && node ../build/tooling/tsc-compiler --project tsconfig.test.json", "pretest-incremental": "npm run build-incremental --silent && cd conf && node ../build/tooling/tsc-compiler --project tsconfig.test.json", "test": "npm run test_buf && npm run test_eslint && npm run test_patterns && npm run test_async_stack && npm run test_ci_chrome_consumer -- -- --pool-size=1", @@ -69,19 +69,19 @@ "test_local_chrome_enterprise_mock": "npm run pretest && npm run test_ci_chrome_enterprise -- -- --pool-size=1 --debug", "test_local_chrome_consumer_live_gmail": "npm run pretest && npm run test_ci_chrome_consumer_live_gmail -- -- --pool-size=1 --debug", "test_local_chrome_consumer_mock_flaky": "npm run pretest && npm run test_ci_chrome_consumer_flaky -- -- --pool-size=1 --retry=false --debug", - "test_local_unit_consumer": "npm run pretest && npx ava --timeout=20m --verbose --concurrency=1 build/test/test/source/test.js -- UNIT-TESTS --retry=false --pool-size=1 --debug CONSUMER-MOCK", - "test_local_unit_enterprise": "npm run pretest && npx ava --timeout=20m --verbose --concurrency=1 build/test/test/source/test.js -- UNIT-TESTS --retry=false --pool-size=1 --debug ENTERPRISE-MOCK", + "test_local_unit_consumer": "npm run pretest && npx ava --timeout=20m --verbose --concurrency=10 build/test/test/source/test.js -- UNIT-TESTS --retry=false --debug CONSUMER-MOCK", + "test_local_unit_enterprise": "npm run pretest && npx ava --timeout=20m --verbose --concurrency=10 build/test/test/source/test.js -- UNIT-TESTS --retry=false --pool-size=1 --debug ENTERPRISE-MOCK", "test_local_chrome_consumer_mock_headless": "xvfb-run npm run test_local_chrome_consumer_mock", "test_stylelint": "stylelint extension/css/cryptup.css extension/css/settings.css extension/css/webmail.css && stylelint extension/**/*.htm --custom-syntax postcss-html", "test_eslint": "eslint --ext ts extension test tooling", "test_patterns": "node build/test/test/source/patterns.js", "test_async_stack": "node build/test/test/source/async-stack.js", - "test_buf": "npx ava --timeout=20m --verbose --concurrency=1 build/test/test/source/buf.js", - "test_ci_chrome_consumer_live_gmail": "npx ava --timeout=20m --verbose --concurrency=1 build/test/test/source/test.js -- CONSUMER-LIVE-GMAIL STANDARD-GROUP", - "test_ci_chrome_consumer": "npx ava --timeout=20m --verbose --concurrency=1 build/test/test/source/test.js -- CONSUMER-MOCK STANDARD-GROUP", - "test_ci_chrome_enterprise": "npx ava --timeout=20m --verbose --concurrency=1 build/test/test/source/test.js -- ENTERPRISE-MOCK STANDARD-GROUP", - "test_ci_chrome_consumer_flaky": "npx ava --timeout=20m --verbose --concurrency=1 build/test/test/source/test.js -- CONSUMER-MOCK FLAKY-GROUP", - "dev_start_gmail_mock_api": "./build.sh && cd ./conf && node ../build/tooling/tsc-compiler --project tsconfig.test.json && cd .. && node ./build/test/test/source/mock.js", + "test_buf": "npx ava --timeout=20m --verbose --concurrency=10 build/test/test/source/buf.js", + "test_ci_chrome_consumer_live_gmail": "npx ava --timeout=20m --verbose --concurrency=10 build/test/test/source/test.js -- CONSUMER-LIVE-GMAIL STANDARD-GROUP", + "test_ci_chrome_consumer": "npx ava --timeout=20m --verbose --concurrency=10 build/test/test/source/test.js -- CONSUMER-MOCK STANDARD-GROUP", + "test_ci_chrome_enterprise": "npx ava --timeout=20m --verbose --concurrency=10 build/test/test/source/test.js -- ENTERPRISE-MOCK STANDARD-GROUP", + "test_ci_chrome_consumer_flaky": "npx ava --timeout=20m --verbose --concurrency=10 build/test/test/source/test.js -- CONSUMER-MOCK FLAKY-GROUP", + "dev_start_gmail_mock_api": "./scripts/build.sh && cd ./conf && node ../build/tooling/tsc-compiler --project tsconfig.test.json && cd .. && node ./build/test/test/source/mock.js", "run_firefox": "npm run build-incremental && npx web-ext run --source-dir ./build/firefox-consumer/ --firefox-profile ~/.mozilla/firefox/flowcrypt-dev --keep-profile-changes", "run_firefox_windows": "npm run build-incremental && npx web-ext run --source-dir ./build/firefox-consumer/ --firefox-profile %userprofile%/AppData/Local/Mozilla/Firefox/Profiles/flowcrypt-dev --keep-profile-changes", "find_unused": "ts-prune -p tsconfig.json | grep -v extension/types | grep -v extension/js/common/core", @@ -109,4 +109,4 @@ "npm run test_stylelint" ] } -} \ No newline at end of file +} diff --git a/build.sh b/scripts/build.sh similarity index 98% rename from build.sh rename to scripts/build.sh index 216a364366d..12915bc7ec6 100755 --- a/build.sh +++ b/scripts/build.sh @@ -78,4 +78,4 @@ node ./build/tooling/bundle-content-scripts cp -r $OUTDIR ./build/chrome-enterprise cp -r $OUTDIR ./build/chrome-consumer cp -r $OUTDIR ./build/firefox-consumer -node ./build/tooling/build-types-and-manifests +node ./build/tooling/build-types-and-manifests \ No newline at end of file diff --git a/scripts/config-mock-build.sh b/scripts/config-mock-build.sh new file mode 100644 index 00000000000..d03193f241f --- /dev/null +++ b/scripts/config-mock-build.sh @@ -0,0 +1,6 @@ +# copy build to new folder and replace all usages of :8001 with appropriate mock port +BUILD_PATH=./build/test/mock-builds/port-$2-$(openssl rand -hex 12) +mkdir -p $BUILD_PATH +cp -r ./$1/* $BUILD_PATH +grep ":8001" $BUILD_PATH -lr | xargs sed -i.bak -e "s/\:8001/\:$2/g" +echo $BUILD_PATH \ No newline at end of file diff --git a/review-branch.sh b/scripts/review-branch.sh similarity index 100% rename from review-branch.sh rename to scripts/review-branch.sh diff --git a/test/debug/puppeteer_cannot_access_iframes/add_iframe/add_iframe.js b/test/debug/puppeteer_cannot_access_iframes/add_iframe/add_iframe.js deleted file mode 100644 index 3d9036b985d..00000000000 --- a/test/debug/puppeteer_cannot_access_iframes/add_iframe/add_iframe.js +++ /dev/null @@ -1,5 +0,0 @@ -window.onload = function () { - var iframe = document.createElement('iframe'); - iframe.src = chrome.runtime.getURL('iframe.htm'); - document.body.appendChild(iframe); -}; diff --git a/test/debug/puppeteer_cannot_access_iframes/add_iframe/iframe.htm b/test/debug/puppeteer_cannot_access_iframes/add_iframe/iframe.htm deleted file mode 100644 index abb99cfd141..00000000000 --- a/test/debug/puppeteer_cannot_access_iframes/add_iframe/iframe.htm +++ /dev/null @@ -1,6 +0,0 @@ - - - - I was added by an extension - - diff --git a/test/debug/puppeteer_cannot_access_iframes/add_iframe/manifest.json b/test/debug/puppeteer_cannot_access_iframes/add_iframe/manifest.json deleted file mode 100644 index 5bc4096aec3..00000000000 --- a/test/debug/puppeteer_cannot_access_iframes/add_iframe/manifest.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "manifest_version": 2, - "name": "Add iframe to google 404 page", - "description": "...", - "version": "0.0.1", - "permissions": ["https://google.com/404"], - "content_scripts": [{ "matches": ["https://google.com/404"], "js": ["add_iframe.js"] }], - "web_accessible_resources": ["iframe.htm"], - "minimum_chrome_version": "55" -} diff --git a/test/debug/puppeteer_cannot_access_iframes/ext-frame-online.js b/test/debug/puppeteer_cannot_access_iframes/ext-frame-online.js deleted file mode 100644 index 554f4173ce1..00000000000 --- a/test/debug/puppeteer_cannot_access_iframes/ext-frame-online.js +++ /dev/null @@ -1,25 +0,0 @@ -const puppeteer = require('../node_modules/puppeteer'); - -let browser; - -(async () => { - browser = await puppeteer.launch({ - args: ['--disable-features=site-per-process', '--disable-extensions-except=add_iframe', '--load-extension=add_iframe'], - headless: false, - slowMo: 50, - }); - - let page = await browser.newPage(); - await page.goto('https://google.com/404'); - - await page.waitForSelector('iframe', { timeout: 5000, visible: true }); - let iframeHandle = await page.$('iframe'); - let iframeSrc = await (await iframeHandle.getProperty('src')).jsonValue(); - - let frames = await page.frames(); - let urls = frames.map(frame => frame.url()); - - console.info(`parsed iframe src: ${iframeSrc}`); - console.info(`page.frames() url: ${JSON.stringify(urls)}`); - console.info(urls.indexOf(iframeSrc) === -1 ? 'FAIL' : 'PASS'); -})(); diff --git a/test/source/browser/browser-handle.ts b/test/source/browser/browser-handle.ts index 493cc71873a..86c84d6dcd2 100644 --- a/test/source/browser/browser-handle.ts +++ b/test/source/browser/browser-handle.ts @@ -1,7 +1,7 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ import { Browser, EvaluateFunc, Page, Target } from 'puppeteer'; -import { Util, Config } from '../util'; +import { Util } from '../util'; import { ControllablePage } from './controllable'; import { Semaphore } from './browser-pool'; import { TIMEOUT_ELEMENT_APPEAR } from '.'; @@ -38,12 +38,29 @@ export class BrowserHandle { await controllablePage.goto(url); } this.pages.push(controllablePage); - if (url && url.includes(Config.extensionId)) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + if (url && url.includes(t.urls!.extensionId)) { await controllablePage.waitUntilViewLoaded(); } return controllablePage; }; + public newExtensionPage = async (t: AvaContext, url: string): Promise => { + return this.newPage(t, t.urls?.extension(url)); + }; + + public newExtensionInboxPage = async (t: AvaContext, acctEmail: string): Promise => { + return this.newPage(t, t.urls?.extensionInbox(acctEmail)); + }; + + public newExtensionSettingsPage = async (t: AvaContext, acctEmail?: string | undefined): Promise => { + return this.newPage(t, t.urls?.extensionSettings(acctEmail)); + }; + + public newMockGmailPage = async (t: AvaContext, extraHeaders?: Record): Promise => { + return this.newPage(t, t.urls?.mockGmailUrl(), undefined, extraHeaders); + }; + public newPageTriggeredBy = async (t: AvaContext, triggeringAction: () => Promise): Promise => { const page = (await this.doAwaitTriggeredPage(triggeringAction)) as Page; const url = page.url(); @@ -51,7 +68,8 @@ export class BrowserHandle { try { await page.setViewport(this.viewport); this.pages.push(controllablePage); - if (url.includes(Config.extensionId)) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + if (url.includes(t.urls!.extensionId)) { await controllablePage.waitUntilViewLoaded(); } return controllablePage; diff --git a/test/source/browser/browser-pool.ts b/test/source/browser/browser-pool.ts index 574be37f232..c6eb743616a 100644 --- a/test/source/browser/browser-pool.ts +++ b/test/source/browser/browser-pool.ts @@ -11,12 +11,10 @@ class TimeoutError extends Error {} export class BrowserPool { private semaphore: Semaphore; - private browsersForReuse: BrowserHandle[] = []; public constructor( public poolSize: number, public name: string, - private reuse: boolean, private extensionBuildDir: string, private isMock: boolean, private width = 1280, @@ -28,14 +26,13 @@ export class BrowserPool { public newBrowserHandle = async (t: AvaContext, closeInitialPage = true) => { await this.semaphore.acquire(); - // ext frames in gmail: https://github.com/GoogleChrome/puppeteer/issues/2506 https://github.com/GoogleChrome/puppeteer/issues/2548 + const extensionDir = t.extensionDir ?? this.extensionBuildDir; const args = [ '--no-sandbox', // make it work in travis-ci '--disable-setuid-sandbox', '--kiosk-printing', - '--disable-features=site-per-process', - `--disable-extensions-except=${this.extensionBuildDir}`, - `--load-extension=${this.extensionBuildDir}`, + `--disable-extensions-except=${extensionDir}`, + `--load-extension=${extensionDir}`, `--window-size=${this.width + 10},${this.height + 132}`, ]; if (this.isMock) { @@ -82,8 +79,7 @@ export class BrowserPool { const extensionUrl = urls.find(url => url !== 'about:blank'); if (extensionUrl) { const match = extensionUrl.match(/[a-z]{32}/); - // eslint-disable-next-line no-null/no-null - if (match !== null) { + if (match) { await browser.close(); return match[0]; } @@ -97,40 +93,6 @@ export class BrowserPool { throw new Error(`Cannot determine extension id from urls.`); }; - public close = async () => { - while (this.browsersForReuse.length) { - await this.browsersForReuse.pop()!.close(); // eslint-disable-line @typescript-eslint/no-non-null-assertion - } - }; - - public openOrReuseBrowser = async (t: AvaContext): Promise => { - if (!this.reuse) { - return await this.newBrowserHandle(t); - } - await this.semaphore.acquire(); - return this.browsersForReuse.pop()!; // eslint-disable-line @typescript-eslint/no-non-null-assertion - }; - - public doneUsingBrowser = async (browser: BrowserHandle) => { - if (this.reuse) { - await browser.closeAllPages(); - this.browsersForReuse.push(browser); - browser.release(); - } else { - await browser.close(); - } - }; - - public getPooledBrowser = async (cb: (t: AvaContext, browser: BrowserHandle) => void, t: AvaContext) => { - const browser = await this.openOrReuseBrowser(t); - try { - await cb(t, browser); - } finally { - await Util.sleep(1); - await this.doneUsingBrowser(browser); - } - }; - public cbWithTimeout = (cb: () => Promise, timeout: number): Promise => { return new Promise((resolve, reject) => { setTimeout(() => reject(new TimeoutError(`Test timed out after ${timeout}ms`)), timeout); // reject in @@ -148,7 +110,7 @@ export class BrowserPool { try { const browser = await withTimeouts(this.newBrowserHandle(t)); try { - await withTimeouts(this.cbWithTimeout(async () => await cb(t, browser), consts.TIMEOUT_EACH_RETRY)); + await withTimeouts(this.cbWithTimeout(async () => cb(t, browser), consts.TIMEOUT_EACH_RETRY)); await this.throwOnRetryFlagAndReset(t); if (attemptDebugHtmls.length && flag !== 'FAILING') { // don't debug known failures diff --git a/test/source/browser/controllable.ts b/test/source/browser/controllable.ts index d3d72ed5f21..adfa3e23c1b 100644 --- a/test/source/browser/controllable.ts +++ b/test/source/browser/controllable.ts @@ -11,12 +11,11 @@ import { TIMEOUT_TEST_STATE_SATISFY, TIMEOUT_FOCUS, } from '.'; -import { TestUrls } from './test-urls'; import { Util } from '../util'; import { expect } from 'chai'; import * as fs from 'fs'; import * as path from 'path'; -import * as mkdirp from 'mkdirp'; +import mkdirp from 'mkdirp'; import { Dict } from '../core/common'; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -275,15 +274,12 @@ abstract class ControllableBase { }; public checkElementColor = async (selector: string, color: string) => { - const elementColor = await this.target.evaluate( - (selector) => { - const el = document.querySelector(selector) as HTMLElement; // this will get evaluated in the browser - return el.style.color; - }, - this.selector(selector) - ); + const elementColor = await this.target.evaluate(selector => { + const el = document.querySelector(selector) as HTMLElement; // this will get evaluated in the browser + return el.style.color; + }, this.selector(selector)); expect(elementColor).to.equal(color); - } + }; public waitAndType = async (selector: string, text: string, { delay = 0.1 }: { delay?: number } = {}) => { await this.waitAll(selector); @@ -387,7 +383,7 @@ abstract class ControllableBase { } throw new Error( `Selector ${selector} was found but did not match "${needle}" within ${timeoutSec}s. ` + - `Observed content history: "${JSON.stringify(observedContentHistory, undefined, 2)}"` + `Observed content history: "${JSON.stringify(observedContentHistory, undefined, 2)}"` ); }; @@ -643,8 +639,7 @@ export class ControllableAlert { } class ConsoleEvent { - // eslint-disable-next-line no-empty-function - public constructor(public type: string, public text: string) { } + public constructor(public type: string, public text: string) {} } export class ControllablePage extends ControllableBase { @@ -661,7 +656,8 @@ export class ControllablePage extends ControllableBase { const response = r.response(); const fail = r.failure(); const url = r.url(); - if (url.indexOf(TestUrls.extension('')) !== 0 || fail) { + const extensionUrl = t.urls?.extension(''); + if ((extensionUrl && url.indexOf(extensionUrl) !== 0) || fail) { // not an extension url, or a fail this.consoleMsgs.push(new ConsoleEvent('request', `${response ? response.status() : '-1'} ${r.method()} ${url}: ${fail ? fail.errorText : 'ok'}`)); } @@ -713,7 +709,11 @@ export class ControllablePage extends ControllableBase { }; public goto = async (url: string) => { - url = url.indexOf('https://') === 0 || url.indexOf(TestUrls.extension('')) === 0 ? url : TestUrls.extension(url); + if (this.t.urls) { + const extensionUrl = this.t.urls.extension(''); + url = url.indexOf('https://') === 0 || url.indexOf(extensionUrl) === 0 ? url : this.t.urls.extension(url); + } + await Util.sleep(1); // await this.page.goto(url); // may produce intermittent Navigation Timeout Exceeded in CI environment this.page.goto(url).catch(e => this.t.log(`goto: ${e.message}: ${url}`)); diff --git a/test/source/browser/test-urls.ts b/test/source/browser/test-urls.ts index fd9b943a236..8b6871ca919 100644 --- a/test/source/browser/test-urls.ts +++ b/test/source/browser/test-urls.ts @@ -1,28 +1,29 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ -import { Config } from '../util'; import { GmailCategory } from '../tests/gmail'; export class TestUrls { - public static extension = (path: string) => { - return `chrome-extension://${Config.extensionId}/${path}`; + public constructor(public extensionId: string, public port: number) {} + + public static googleChat = (acctLoginIndex = 0) => { + return `https://mail.google.com/chat/u/${acctLoginIndex}`; }; - public static extensionSettings = (acctEmail?: string | undefined) => { - return TestUrls.extension(`chrome/settings/index.htm?account_email=${acctEmail || ''}`); + public static gmail = (acctLoginIndex = 0, urlEnd = '', category: GmailCategory = 'inbox') => { + return `https://mail.google.com/mail/u/${acctLoginIndex}/#${category}${urlEnd}`; }; - public static extensionInbox = (acctEmail: string) => { - return TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}`); + public extension = (path: string) => { + return `chrome-extension://${this.extensionId}/${path}`; }; - public static gmail = (acctLoginIndex = 0, urlEnd = '', category: GmailCategory = 'inbox') => { - return `https://mail.google.com/mail/u/${acctLoginIndex}/#${category}${urlEnd}`; + public extensionSettings = (acctEmail?: string | undefined) => { + return this.extension(`chrome/settings/index.htm?account_email=${acctEmail || ''}`); }; - public static googleChat = (acctLoginIndex = 0) => { - return `https://mail.google.com/chat/u/${acctLoginIndex}`; + public extensionInbox = (acctEmail: string) => { + return this.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}`); }; - public static mockGmailUrl = () => 'https://gmail.localhost:8001/gmail'; + public mockGmailUrl = () => `https://gmail.localhost:${this.port}/gmail`; } diff --git a/test/source/buf.ts b/test/source/buf.ts index 7fe152b225e..d0d915651a8 100644 --- a/test/source/buf.ts +++ b/test/source/buf.ts @@ -1,6 +1,6 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ -import * as ava from 'ava'; +import test from 'ava'; import { Buf } from '../../extension/js/common/core/buf.js'; import { equals } from './tests/unit-node.js'; @@ -26,67 +26,67 @@ const UTF8 = `გამარჯობა.\nこんにちは。\nЗдравств const UTF8_AS_BYTES = Buffer.from(UTF8); const UTF8_AS_RAW_STRING = Buffer.from(UTF8).toString('binary'); -ava.default(`1000x Buf.fromUint8(data).toBase64Str() = Buffer.from(data).toString('base64')`, async t => { +test(`1000x Buf.fromUint8(data).toBase64Str() = Buffer.from(data).toString('base64')`, async t => { withThousandRandomInputs(data => { equals(Buf.fromUint8(data).toBase64Str(), Buffer.from(data).toString('base64')); }); t.pass(); }); -ava.default(`1000x Buf.fromUint8(data).toRawBytesStr() = Buffer.from(data).toString('binary')`, async t => { +test(`1000x Buf.fromUint8(data).toRawBytesStr() = Buffer.from(data).toString('binary')`, async t => { withThousandRandomInputs(data => { equals(Buf.fromUint8(data).toRawBytesStr(), Buffer.from(data).toString('binary')); }); t.pass(); }); -ava.default('1000x Buf.fromBase64UrlStr(Buf.fromUint8(data).toBase64UrlStr()) = data', async t => { +test('1000x Buf.fromBase64UrlStr(Buf.fromUint8(data).toBase64UrlStr()) = data', async t => { withThousandRandomInputs(data => { equals(Buf.fromBase64UrlStr(Buf.fromUint8(data).toBase64UrlStr()), data); }); t.pass(); }); -ava.default('1000x Buf.fromRawBytesStr(Buf.fromUint8(data).toRawBytesStr()) = data', async t => { +test('1000x Buf.fromRawBytesStr(Buf.fromUint8(data).toRawBytesStr()) = data', async t => { withThousandRandomInputs(data => { equals(Buf.fromRawBytesStr(Buf.fromUint8(data).toRawBytesStr()), data); }); t.pass(); }); -ava.default('1000x Buf.fromBase64Str(Buf.fromUint8(data).toBase64Str()) = data', async t => { +test('1000x Buf.fromBase64Str(Buf.fromUint8(data).toBase64Str()) = data', async t => { withThousandRandomInputs(data => { equals(Buf.fromBase64Str(Buf.fromUint8(data).toBase64Str()), data); }); t.pass(); }); -ava.default('Buf.fromUtfStr(UTF8) = UTF8_AS_BYTES', async t => { +test('Buf.fromUtfStr(UTF8) = UTF8_AS_BYTES', async t => { equals(Buf.fromUtfStr(UTF8), UTF8_AS_BYTES); t.pass(); }); -ava.default('Buf.fromUint8(UTF8_AS_BYTES).toUtfStr() = UTF8', async t => { +test('Buf.fromUint8(UTF8_AS_BYTES).toUtfStr() = UTF8', async t => { equals(Buf.fromUint8(UTF8_AS_BYTES).toUtfStr(), UTF8); t.pass(); }); -ava.default('Buf.fromRawBytesStr(UTF8_AS_RAW_STRING).toUtfStr() = UTF8', async t => { +test('Buf.fromRawBytesStr(UTF8_AS_RAW_STRING).toUtfStr() = UTF8', async t => { equals(Buf.fromRawBytesStr(UTF8_AS_RAW_STRING).toUtfStr(), UTF8); t.pass(); }); -ava.default('Buf.fromUtfStr(UTF8).toRawBytesStr() = UTF8_AS_RAW_STRING', async t => { +test('Buf.fromUtfStr(UTF8).toRawBytesStr() = UTF8_AS_RAW_STRING', async t => { equals(Buf.fromUtfStr(UTF8).toRawBytesStr(), UTF8_AS_RAW_STRING); t.pass(); }); -ava.default('Buf.fromRawBytesStr(UTF8_AS_RAW_STRING) = UTF8_AS_BYTES', async t => { +test('Buf.fromRawBytesStr(UTF8_AS_RAW_STRING) = UTF8_AS_BYTES', async t => { equals(Buf.fromRawBytesStr(UTF8_AS_RAW_STRING), UTF8_AS_BYTES); t.pass(); }); -ava.default('Buf.fromUint8(UTF8_AS_BYTES) = UTF8_AS_RAW_STRING', async t => { +test('Buf.fromUint8(UTF8_AS_BYTES) = UTF8_AS_RAW_STRING', async t => { equals(Buf.fromUint8(UTF8_AS_BYTES).toRawBytesStr(), UTF8_AS_RAW_STRING); t.pass(); }); diff --git a/test/source/mock.ts b/test/source/mock.ts deleted file mode 100644 index 085aa54a589..00000000000 --- a/test/source/mock.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ - -import { startAllApisMock } from './mock/all-apis-mock'; - -export const mock = async (logger: (line: string) => void) => { - return await startAllApisMock(logger); -}; - -if (require.main === module) { - mock(msgLog => console.log(msgLog)).catch(e => { - console.error(e); - process.exit(1); - }); -} diff --git a/test/source/mock/all-apis-mock.ts b/test/source/mock/all-apis-mock.ts index d609c111ed2..e16ee3e181e 100644 --- a/test/source/mock/all-apis-mock.ts +++ b/test/source/mock/all-apis-mock.ts @@ -36,6 +36,6 @@ export const startAllApisMock = async (logger: (line: string) => void) => { ...mockSharedTenantFesEndpoints, '/favicon.ico': async () => '', }); - await api.listen(8001); + await api.listen(); return api; }; diff --git a/test/source/mock/backend/backend-data.ts b/test/source/mock/backend/backend-data.ts index 10a4e40e527..1b11564552b 100644 --- a/test/source/mock/backend/backend-data.ts +++ b/test/source/mock/backend/backend-data.ts @@ -4,11 +4,13 @@ import { Dict } from '../../core/common'; import { HttpClientErr } from '../lib/api'; /* eslint-disable @typescript-eslint/naming-convention */ -export const keyManagerAutogenRules = { - flags: ['NO_PRV_BACKUP', 'ENFORCE_ATTESTER_SUBMIT', 'PRV_AUTOIMPORT_OR_AUTOGEN', 'PASS_PHRASE_QUIET_AUTOGEN', 'DEFAULT_REMEMBER_PASS_PHRASE'], - key_manager_url: 'https://localhost:8001/flowcrypt-email-key-manager', - enforce_keygen_algo: 'rsa2048', - disallow_attester_search_for_domains: [], +export const keyManagerAutogenRules = (port: string) => { + return { + flags: ['NO_PRV_BACKUP', 'ENFORCE_ATTESTER_SUBMIT', 'PRV_AUTOIMPORT_OR_AUTOGEN', 'PASS_PHRASE_QUIET_AUTOGEN', 'DEFAULT_REMEMBER_PASS_PHRASE'], + key_manager_url: `https://localhost:${port}/flowcrypt-email-key-manager`, + enforce_keygen_algo: 'rsa2048', + disallow_attester_search_for_domains: [], + }; }; export type ClientConfiguration = { @@ -43,7 +45,7 @@ export class BackendData { /* eslint-disable no-null/no-null */ /* eslint-disable @typescript-eslint/naming-convention */ - public getClientConfiguration = (domain: string) => { + public getClientConfiguration = (domain: string, port: string) => { const foundConfiguration = this.clientConfigurationForDomain[domain]; if (foundConfiguration) { if (foundConfiguration instanceof HttpClientErr) { @@ -51,6 +53,7 @@ export class BackendData { } return foundConfiguration; } + const keyManagerRules = keyManagerAutogenRules(port); if (domain === 'client-configuration-test.flowcrypt.test') { return { flags: ['NO_PRV_CREATE', 'NO_PRV_BACKUP', 'HIDE_ARMOR_META', 'ENFORCE_ATTESTER_SUBMIT', 'SETUP_ENSURE_IMPORTED_PRV_MATCH_LDAP_PUB'], @@ -75,8 +78,8 @@ export class BackendData { } if (domain === 'custom-sks.flowcrypt.test') { return { - ...keyManagerAutogenRules, - custom_keyserver_url: 'https://localhost:8001', + ...keyManagerRules, + custom_keyserver_url: `https://localhost:${port}`, }; } if (domain === 'forbid-storing-passphrase-client-configuration.flowcrypt.test') { @@ -114,42 +117,42 @@ export class BackendData { allow_attester_search_only_for_domains: [], }; } - if (domain === 'google.mock.localhost:8001') { - return { ...keyManagerAutogenRules, flags: [...keyManagerAutogenRules.flags, 'NO_ATTESTER_SUBMIT'] }; + if (domain === `google.mock.localhost:${port}`) { + return { ...keyManagerRules, flags: [...keyManagerRules.flags, 'NO_ATTESTER_SUBMIT'] }; } if (domain === 'key-manager-autogen.flowcrypt.test') { - return keyManagerAutogenRules; + return keyManagerRules; } if (domain === 'key-manager-autoimport-no-prv-create.flowcrypt.test') { - return { ...keyManagerAutogenRules, flags: [...keyManagerAutogenRules.flags, 'NO_PRV_CREATE'] }; + return { ...keyManagerRules, flags: [...keyManagerRules.flags, 'NO_PRV_CREATE'] }; } if (domain === 'key-manager-disabled-password-message.flowcrypt.test') { return { - ...keyManagerAutogenRules, - flags: [...keyManagerAutogenRules.flags, 'DISABLE_FLOWCRYPT_HOSTED_PASSWORD_MESSAGES'], + ...keyManagerRules, + flags: [...keyManagerRules.flags, 'DISABLE_FLOWCRYPT_HOSTED_PASSWORD_MESSAGES'], }; } if (domain === 'key-manager-autoimport-no-prv-create-no-attester-submit.flowcrypt.test') { return { - ...keyManagerAutogenRules, - flags: [...keyManagerAutogenRules.flags, 'NO_PRV_CREATE', 'NO_ATTESTER_SUBMIT'], + ...keyManagerRules, + flags: [...keyManagerRules.flags, 'NO_PRV_CREATE', 'NO_ATTESTER_SUBMIT'], }; } if (domain === 'key-manager-choose-passphrase.flowcrypt.test') { return { - ...keyManagerAutogenRules, + ...keyManagerRules, flags: ['NO_PRV_BACKUP', 'PRV_AUTOIMPORT_OR_AUTOGEN', 'NO_ATTESTER_SUBMIT', 'DEFAULT_REMEMBER_PASS_PHRASE'], }; } if (domain === 'key-manager-choose-passphrase-forbid-storing.flowcrypt.test') { return { - ...keyManagerAutogenRules, + ...keyManagerRules, flags: ['NO_PRV_BACKUP', 'PRV_AUTOIMPORT_OR_AUTOGEN', 'NO_ATTESTER_SUBMIT', 'FORBID_STORING_PASS_PHRASE'], }; } if (domain === 'key-manager-server-offline.flowcrypt.test') { // EKM offline during local key autogen / upload to EKM flow - return { ...keyManagerAutogenRules, key_manager_url: 'https://localhost:1230/intentionally-wrong' }; + return { ...keyManagerRules, key_manager_url: 'https://localhost:1230/intentionally-wrong' }; } if (domain === 'ekm-offline-retrieve.flowcrypt.test') { return { @@ -159,10 +162,10 @@ export class BackendData { }; } if (domain === 'key-manager-keygen-expiration.flowcrypt.test') { - return { ...keyManagerAutogenRules, enforce_keygen_expire_months: 1 }; + return { ...keyManagerRules, enforce_keygen_expire_months: 1 }; } if (domain === 'no-submit-client-configuration.key-manager-autogen.flowcrypt.test') { - return { ...keyManagerAutogenRules, flags: [...keyManagerAutogenRules.flags, 'NO_ATTESTER_SUBMIT'] }; + return { ...keyManagerRules, flags: [...keyManagerRules.flags, 'NO_ATTESTER_SUBMIT'] }; } if (domain === 'prv-create-no-prv-backup.flowcrypt.test') { // org is allowed to create new keys in the plugin, without EKM, but no backups are allowed diff --git a/test/source/mock/fes/customer-url-fes-endpoints.ts b/test/source/mock/fes/customer-url-fes-endpoints.ts index 7df43fbaa7d..8159046a0c8 100644 --- a/test/source/mock/fes/customer-url-fes-endpoints.ts +++ b/test/source/mock/fes/customer-url-fes-endpoints.ts @@ -6,12 +6,15 @@ import { Buf } from '../../core/buf'; import { MsgUtil } from '../../core/crypto/pgp/msg-util'; import { HandlersDefinition } from '../all-apis-mock'; import { HttpClientErr, Status } from '../lib/api'; +import { parsePort } from '../lib/mock-util'; import { MockJwt } from '../lib/oauth'; -const standardFesUrl = 'fes.standardsubdomainfes.localhost:8001'; +const standardFesUrl = (port: string) => { + return `fes.standardsubdomainfes.localhost:${port}`; +}; const issuedAccessTokens: string[] = []; -const processMessageFromUser = async (body: string) => { +const processMessageFromUser = async (body: string, fesUrl: string) => { expect(body).to.contain('-----BEGIN PGP MESSAGE-----'); expect(body).to.contain('"associateReplyToken":"mock-fes-reply-token"'); expect(body).to.contain('"to":["Mr To "]'); @@ -26,8 +29,7 @@ const processMessageFromUser = async (body: string) => { verificationPubs: [], }); expect(decrypted.success).to.equal(true); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const decryptedMimeMsg = decrypted.content!.toUtfStr(); + const decryptedMimeMsg = decrypted.content?.toUtfStr(); expect(decryptedMimeMsg).to.contain( 'Content-Type: text/plain\r\n' + 'Content-Transfer-Encoding: quoted-printable\r\n\r\n' + 'PWD encrypted message with FES - ID TOKEN' ); @@ -36,22 +38,22 @@ const processMessageFromUser = async (body: string) => { expect(decryptedMimeMsg).to.contain('Content-Transfer-Encoding: base64\r\n\r\n' + 'c21hbGwgdGV4dCBmaWxlCm5vdCBtdWNoIGhlcmUKdGhpcyB3b3JrZWQK'); const response = { // this url is required for pubkey encrypted message - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-ID`, externalId: 'FES-MOCK-EXTERNAL-ID', emailToExternalIdAndUrl: {} as { [email: string]: { url: string; externalId: string } }, }; response.emailToExternalIdAndUrl['to@example.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-TO@EXAMPLE.COM-ID', }; response.emailToExternalIdAndUrl['bcc@example.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-BCC@EXAMPLE.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-BCC@EXAMPLE.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-BCC@EXAMPLE.COM-ID', }; return response; }; -const processMessageFromUser2 = async (body: string) => { +const processMessageFromUser2 = async (body: string, fesUrl: string) => { expect(body).to.contain('-----BEGIN PGP MESSAGE-----'); expect(body).to.contain('"associateReplyToken":"mock-fes-reply-token"'); expect(body).to.contain('"to":["sender@domain.com","flowcrypt.compatibility@gmail.com","to@example.com","mock.only.pubkey@flowcrypt.com"]'); @@ -66,8 +68,7 @@ const processMessageFromUser2 = async (body: string) => { verificationPubs: [], }); expect(decrypted.success).to.equal(true); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const decryptedMimeMsg = decrypted.content!.toUtfStr(); + const decryptedMimeMsg = decrypted.content?.toUtfStr(); // small.txt expect(decryptedMimeMsg).to.contain('Content-Type: text/plain; name=small.txt\r\n' + 'Content-Disposition: attachment; filename=small.txt'); expect(decryptedMimeMsg).to.contain('Content-Transfer-Encoding: base64\r\n\r\n' + 'c21hbGwgdGV4dCBmaWxlCm5vdCBtdWNoIGhlcmUKdGhpcyB3b3JrZWQK'); @@ -78,30 +79,30 @@ const processMessageFromUser2 = async (body: string) => { ); const response = { // this url is required for pubkey encrypted message - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-ID`, externalId: 'FES-MOCK-EXTERNAL-ID', emailToExternalIdAndUrl: {} as { [email: string]: { url: string; externalId: string } }, }; response.emailToExternalIdAndUrl['to@example.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-TO@EXAMPLE.COM-ID', }; response.emailToExternalIdAndUrl['sender@domain.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-SENDER@DOMAIN.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-SENDER@DOMAIN.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-SENDER@DOMAIN.COM-ID', }; response.emailToExternalIdAndUrl['flowcrypt.compatibility@gmail.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-FLOWCRYPT.COMPATIBILITY@GMAIL.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-FLOWCRYPT.COMPATIBILITY@GMAIL.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-FLOWCRYPT.COMPATIBILITY@GMAIL.COM-ID', }; response.emailToExternalIdAndUrl['mock.only.pubkey@flowcrypt.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-MOCK.ONLY.PUBKEY@FLOWCRYPT.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-MOCK.ONLY.PUBKEY@FLOWCRYPT.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-MOCK.ONLY.PUBKEY@FLOWCRYPT.COM-ID', }; return response; }; -const processMessageFromUser3 = async (body: string) => { +const processMessageFromUser3 = async (body: string, fesUrl: string) => { expect(body).to.contain('-----BEGIN PGP MESSAGE-----'); expect(body).to.contain('"associateReplyToken":"mock-fes-reply-token"'); expect(body).to.contain('"to":["to@example.com"]'); @@ -116,69 +117,68 @@ const processMessageFromUser3 = async (body: string) => { verificationPubs: [], }); expect(decrypted.success).to.equal(true); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const decryptedMimeMsg = decrypted.content!.toUtfStr(); + const decryptedMimeMsg = decrypted.content?.toUtfStr(); // small.txt expect(decryptedMimeMsg).to.contain( 'Content-Type: text/plain\r\n' + 'Content-Transfer-Encoding: quoted-printable\r\n\r\n' + 'PWD encrypted message with FES - pubkey recipient in bcc' ); const response = { // this url is required for pubkey encrypted message - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-ID`, externalId: 'FES-MOCK-EXTERNAL-ID', emailToExternalIdAndUrl: {} as { [email: string]: { url: string; externalId: string } }, }; response.emailToExternalIdAndUrl['to@example.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-TO@EXAMPLE.COM-ID', }; response.emailToExternalIdAndUrl['flowcrypt.compatibility@gmail.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-FLOWCRYPT.COMPATIBILITY@GMAIL.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-FLOWCRYPT.COMPATIBILITY@GMAIL.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-FLOWCRYPT.COMPATIBILITY@GMAIL.COM-ID', }; return response; }; -const processMessageFromUser4 = async (body: string) => { +const processMessageFromUser4 = async (body: string, fesUrl: string) => { const response = { // this url is required for pubkey encrypted message - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-ID`, externalId: 'FES-MOCK-EXTERNAL-ID', emailToExternalIdAndUrl: {} as { [email: string]: { url: string; externalId: string } }, }; if (body.includes('to@example.com')) { response.emailToExternalIdAndUrl['to@example.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-TO@EXAMPLE.COM-ID', }; } if (body.includes('invalid@example.com')) { response.emailToExternalIdAndUrl['invalid@example.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-INVALID@EXAMPLE.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-INVALID@EXAMPLE.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-INVALID@EXAMPLE.COM-ID', }; } if (body.includes('timeout@example.com')) { response.emailToExternalIdAndUrl['timeout@example.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-TIMEOUT@EXAMPLE.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-TIMEOUT@EXAMPLE.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-TIMEOUT@EXAMPLE.COM-ID', }; } if (body.includes('Mr Cc ')) { response.emailToExternalIdAndUrl['cc@example.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-CC@EXAMPLE.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-CC@EXAMPLE.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-CC@EXAMPLE.COM-ID', }; } if (body.includes('First Last ')) { response.emailToExternalIdAndUrl['flowcrypt.compatibility@gmail.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-FLOWCRYPT.COMPATIBILITY@GMAIL.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-FLOWCRYPT.COMPATIBILITY@GMAIL.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-FLOWCRYPT.COMPATIBILITY@GMAIL.COM-ID', }; } if (body.includes('gatewayfailure@example.com')) { response.emailToExternalIdAndUrl['gatewayfailure@example.com'] = { - url: `http://${standardFesUrl}/message/FES-MOCK-MESSAGE-FOR-GATEWAYFAILURE@EXAMPLE.COM-ID`, + url: `http://${fesUrl}/message/FES-MOCK-MESSAGE-FOR-GATEWAYFAILURE@EXAMPLE.COM-ID`, externalId: 'FES-MOCK-EXTERNAL-FOR-GATEWAYFAILURE@EXAMPLE.COM-ID', }; } @@ -188,7 +188,8 @@ const processMessageFromUser4 = async (body: string) => { export const mockCustomerUrlFesEndpoints: HandlersDefinition = { // standard fes location at https://fes.domain.com '/api/': async ({}, req) => { - if ([standardFesUrl].includes(req.headers.host || '') && req.method === 'GET') { + const port = parsePort(req); + if ([standardFesUrl(port)].includes(req.headers.host || '') && req.method === 'GET') { return { vendor: 'Mock', service: 'external-service', @@ -197,12 +198,12 @@ export const mockCustomerUrlFesEndpoints: HandlersDefinition = { apiVersion: 'v1', }; } - if (req.headers.host === 'fes.localhost:8001') { + if (req.headers.host === `fes.localhost:${port}`) { // test `status404 does not return any fesUrl` uses this // this makes enterprise version tolerate missing FES - explicit 404 throw new HttpClientErr(`Not found`, 404); } - if (req.headers.host === 'fes.google.mock.localhost:8001') { + if (req.headers.host === `fes.google.mock.localhost:${port}`) { // test `compose - auto include pubkey is inactive when our key is available on Wkd` uses this // this makes enterprise version tolerate missing FES - explicit 404 throw new HttpClientErr(`Not found`, 404); @@ -214,7 +215,8 @@ export const mockCustomerUrlFesEndpoints: HandlersDefinition = { if (req.method !== 'GET') { throw new HttpClientErr('Unsupported method'); } - if (req.headers.host === standardFesUrl && req.url === `/api/v1/client-configuration?domain=standardsubdomainfes.localhost:8001`) { + const port = parsePort(req); + if (req.headers.host === standardFesUrl(port) && req.url === `/api/v1/client-configuration?domain=standardsubdomainfes.localhost:${port}`) { return { clientConfiguration: { flags: [], disallow_attester_search_for_domains: ['got.this@fromstandardfes.com'] }, // eslint-disable-line @typescript-eslint/naming-convention }; @@ -222,67 +224,73 @@ export const mockCustomerUrlFesEndpoints: HandlersDefinition = { throw new HttpClientErr(`Unexpected FES domain "${req.headers.host}" and url "${req.url}"`); }, '/api/v1/message/new-reply-token': async ({}, req) => { - if (req.headers.host === standardFesUrl && req.method === 'POST') { + if (req.headers.host === standardFesUrl(parsePort(req)) && req.method === 'POST') { authenticate(req, 'oidc'); return { replyToken: 'mock-fes-reply-token' }; } throw new HttpClientErr('Not Found', 404); }, '/api/v1/message': async ({ body }, req) => { + const port = parsePort(req); + const fesUrl = standardFesUrl(port); // body is a mime-multipart string, we're doing a few smoke checks here without parsing it - if (req.headers.host === standardFesUrl && req.method === 'POST' && typeof body === 'string') { + if (req.headers.host === fesUrl && req.method === 'POST' && typeof body === 'string') { // test: `compose - user@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal` authenticate(req, 'oidc'); - if (body.includes('"from":"user@standardsubdomainfes.localhost:8001"')) { - return await processMessageFromUser(body); + if (body.includes(`"from":"user@standardsubdomainfes.localhost:${port}"`)) { + return await processMessageFromUser(body, fesUrl); } - if (body.includes('"from":"user2@standardsubdomainfes.localhost:8001"')) { - return await processMessageFromUser2(body); + if (body.includes(`"from":"user2@standardsubdomainfes.localhost:${port}"`)) { + return await processMessageFromUser2(body, fesUrl); } - if (body.includes('"from":"user3@standardsubdomainfes.localhost:8001"')) { - return await processMessageFromUser3(body); + if (body.includes(`"from":"user3@standardsubdomainfes.localhost:${port}"`)) { + return await processMessageFromUser3(body, fesUrl); } - if (body.includes('"from":"user4@standardsubdomainfes.localhost:8001"')) { - return await processMessageFromUser4(body); + if (body.includes(`"from":"user4@standardsubdomainfes.localhost:${port}"`)) { + return await processMessageFromUser4(body, fesUrl); } } throw new HttpClientErr('Not Found', 404); }, '/api/v1/message/FES-MOCK-EXTERNAL-ID/gateway': async ({ body }, req) => { - if (req.headers.host === standardFesUrl && req.method === 'POST') { + const port = parsePort(req); + if (req.headers.host === standardFesUrl(port) && req.method === 'POST') { // test: `compose - user@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal` authenticate(req, 'oidc'); - expect(body).to.match(/{"emailGatewayMessageId":"<(.+)@standardsubdomainfes.localhost:8001>"}/); + expect(body).to.match(messageIdRegex(port)); return {}; } throw new HttpClientErr('Not Found', 404); }, '/api/v1/message/FES-MOCK-EXTERNAL-FOR-SENDER@DOMAIN.COM-ID/gateway': async ({ body }, req) => { - if (req.headers.host === standardFesUrl && req.method === 'POST') { + const port = parsePort(req); + if (req.headers.host === standardFesUrl(port) && req.method === 'POST') { // test: `compose - user2@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES - Reply rendering` authenticate(req, 'oidc'); - expect(body).to.match(/{"emailGatewayMessageId":"<(.+)@standardsubdomainfes.localhost:8001>"}/); + expect(body).to.match(messageIdRegex(port)); return {}; } throw new HttpClientErr('Not Found', 404); }, '/api/v1/message/FES-MOCK-EXTERNAL-FOR-TO@EXAMPLE.COM-ID/gateway': async ({ body }, req) => { - if (req.headers.host === standardFesUrl && req.method === 'POST') { + const port = parsePort(req); + if (req.headers.host === standardFesUrl(port) && req.method === 'POST') { // test: `compose - user@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal` // test: `compose - user2@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES - Reply rendering` // test: `compose - user3@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal - pubkey recipient in bcc` // test: `compose - user4@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal - some sends fail with BadRequest error` authenticate(req, 'oidc'); - expect(body).to.match(/{"emailGatewayMessageId":"<(.+)@standardsubdomainfes.localhost:8001>"}/); + expect(body).to.match(messageIdRegex(port)); return {}; } throw new HttpClientErr('Not Found', 404); }, '/api/v1/message/FES-MOCK-EXTERNAL-FOR-BCC@EXAMPLE.COM-ID/gateway': async ({ body }, req) => { - if (req.headers.host === standardFesUrl && req.method === 'POST') { + const port = parsePort(req); + if (req.headers.host === standardFesUrl(port) && req.method === 'POST') { // test: `compose - user@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal` authenticate(req, 'oidc'); - expect(body).to.match(/{"emailGatewayMessageId":"<(.+)@standardsubdomainfes.localhost:8001>"}/); + expect(body).to.match(messageIdRegex(port)); return {}; } throw new HttpClientErr('Not Found', 404); @@ -310,3 +318,7 @@ const authenticate = (req: IncomingMessage, type: 'oidc' | 'fes'): string => { } return MockJwt.parseEmail(jwt); }; + +const messageIdRegex = (port: string) => { + return new RegExp(`{"emailGatewayMessageId":"<(.+)@standardsubdomainfes.localhost:${port}>"}`); +}; diff --git a/test/source/mock/fes/shared-tenant-fes-endpoints.ts b/test/source/mock/fes/shared-tenant-fes-endpoints.ts index be5fc1e6d02..56d3f02f056 100644 --- a/test/source/mock/fes/shared-tenant-fes-endpoints.ts +++ b/test/source/mock/fes/shared-tenant-fes-endpoints.ts @@ -6,6 +6,7 @@ import { HandlersDefinition } from '../all-apis-mock'; import { HttpClientErr, Status } from '../lib/api'; import { MockJwt } from '../lib/oauth'; import { mockBackendData } from '../backend/backend-endpoints'; +import { parsePort } from '../lib/mock-util'; const issuedAccessTokens: string[] = []; export const mockSharedTenantFesEndpoints: HandlersDefinition = { @@ -20,12 +21,13 @@ export const mockSharedTenantFesEndpoints: HandlersDefinition = { apiVersion: 'v1', }; } - if (req.headers.host === 'fes.localhost:8001') { + const port = parsePort(req); + if (req.headers.host === `fes.localhost:${port}`) { // test `status404 does not return any fesUrl` uses this // this makes enterprise version tolerate missing FES - explicit 404 throw new HttpClientErr(`Not found`, 404); } - if (req.headers.host === 'fes.google.mock.localhost:8001') { + if (req.headers.host === `fes.google.mock.localhost:${port}`) { // test `compose - auto include pubkey is inactive when our key is available on Wkd` uses this // this makes enterprise version tolerate missing FES - explicit 404 throw new HttpClientErr(`Not found`, 404); @@ -38,7 +40,7 @@ export const mockSharedTenantFesEndpoints: HandlersDefinition = { throw new HttpClientErr('Unsupported method'); } return { - clientConfiguration: mockBackendData.getClientConfiguration(domain), + clientConfiguration: mockBackendData.getClientConfiguration(domain, parsePort(req)), }; }, '/shared-tenant-fes/api/v1/message/new-reply-token': async ({}, req) => { @@ -67,7 +69,7 @@ export const mockSharedTenantFesEndpoints: HandlersDefinition = { if (req.method === 'POST') { // test: `compose - user@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal` authenticate(req, 'oidc'); - expect(body).to.match(/{"emailGatewayMessageId":"<(.+)@standardsubdomainfes.localhost:8001>"}/); + expect(body).to.match(messageIdRegex(req)); return {}; } throw new HttpClientErr('Not Found', 404); @@ -76,7 +78,7 @@ export const mockSharedTenantFesEndpoints: HandlersDefinition = { if (req.method === 'POST') { // test: `compose - user2@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES - Reply rendering` authenticate(req, 'oidc'); - expect(body).to.match(/{"emailGatewayMessageId":"<(.+)@standardsubdomainfes.localhost:8001>"}/); + expect(body).to.match(messageIdRegex(req)); return {}; } throw new HttpClientErr('Not Found', 404); @@ -88,7 +90,7 @@ export const mockSharedTenantFesEndpoints: HandlersDefinition = { // test: `compose - user3@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal - pubkey recipient in bcc` // test: `compose - user4@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal - some sends fail with BadRequest error` authenticate(req, 'oidc'); - expect(body).to.match(/{"emailGatewayMessageId":"<(.+)@standardsubdomainfes.localhost:8001>"}/); + expect(body).to.match(messageIdRegex(req)); return {}; } throw new HttpClientErr('Not Found', 404); @@ -97,7 +99,7 @@ export const mockSharedTenantFesEndpoints: HandlersDefinition = { if (req.method === 'POST') { // test: `compose - user@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal` authenticate(req, 'oidc'); - expect(body).to.match(/{"emailGatewayMessageId":"<(.+)@standardsubdomainfes.localhost:8001>"}/); + expect(body).to.match(messageIdRegex(req)); return {}; } throw new HttpClientErr('Not Found', 404); @@ -125,3 +127,8 @@ const authenticate = (req: IncomingMessage, type: 'oidc' | 'fes'): string => { } return MockJwt.parseEmail(jwt); }; + +const messageIdRegex = (req: IncomingMessage) => { + const port = parsePort(req); + return new RegExp(`{"emailGatewayMessageId":"<(.+)@standardsubdomainfes.localhost:${port}>"}`); +}; diff --git a/test/source/mock/google/google-data.ts b/test/source/mock/google/google-data.ts index b40894c24b4..c9e564a2455 100644 --- a/test/source/mock/google/google-data.ts +++ b/test/source/mock/google/google-data.ts @@ -63,15 +63,13 @@ export class GmailMsg { this.threadId = msg.id; this.labelIds = [msg.labelId]; this.raw = msg.raw; - /* eslint-disable @typescript-eslint/no-non-null-assertion */ - const contentTypeHeader = msg.mimeMsg.headers.get('content-type')! as StructuredHeader; - const toHeader = msg.mimeMsg.headers.get('to')! as AddressObject; - const fromHeader = msg.mimeMsg.headers.get('from')! as AddressObject; - const subjectHeader = msg.mimeMsg.headers.get('subject')! as string; - const dateHeader = msg.mimeMsg.headers.get('date')! as Date; - const messageIdHeader = msg.mimeMsg.headers.get('message-id')! as string; - const mimeVersionHeader = msg.mimeMsg.headers.get('mime-version')! as string; - /* eslint-enable @typescript-eslint/no-non-null-assertion */ + const contentTypeHeader = msg.mimeMsg.headers.get('content-type') as StructuredHeader; + const toHeader = msg.mimeMsg.headers.get('to') as AddressObject; + const fromHeader = msg.mimeMsg.headers.get('from') as AddressObject; + const subjectHeader = msg.mimeMsg.headers.get('subject') as string; + const dateHeader = msg.mimeMsg.headers.get('date') as Date; + const messageIdHeader = msg.mimeMsg.headers.get('message-id') as string; + const mimeVersionHeader = msg.mimeMsg.headers.get('mime-version') as string; let body: GmailMsg$payload$body | undefined; if (msg.mimeMsg.text) { const textBase64 = Buffer.from(msg.mimeMsg.text, 'utf-8').toString('base64'); @@ -92,20 +90,18 @@ export class GmailMsg { ], body, }; - /* eslint-disable @typescript-eslint/no-non-null-assertion */ if (toHeader) { - this.payload.headers!.push({ name: 'To', value: toHeader.value.map(a => a.address).join(',') }); + this.payload.headers?.push({ name: 'To', value: toHeader.value.map(a => a.address).join(',') }); } - if (fromHeader) { - this.payload.headers!.push({ name: 'From', value: fromHeader.value[0].address! }); + if (fromHeader && fromHeader.value[0].address) { + this.payload.headers?.push({ name: 'From', value: fromHeader.value[0].address }); } if (subjectHeader) { - this.payload.headers!.push({ name: 'Subject', value: subjectHeader }); + this.payload.headers?.push({ name: 'Subject', value: subjectHeader }); } if (dateHeader) { - this.payload.headers!.push({ name: 'Date', value: dateHeader.toString() }); + this.payload.headers?.push({ name: 'Date', value: dateHeader.toString() }); } - /* eslint-enable @typescript-eslint/no-non-null-assertion */ } } @@ -181,7 +177,7 @@ export class GoogleData { for (const file of files) { const utfStr = new TextDecoder().decode(file); const json = JSON.parse(utfStr) as ExportedMsg; - if (json.acctEmail === acct) { + if (json.acctEmail.split(':')[0] === acct.split(':')[0]) { Object.assign(acctData.attachments, json.attachments); json.full.raw = json.raw.raw; if (json.full.labelIds && json.full.labelIds.includes('DRAFT')) { @@ -242,7 +238,7 @@ export class GoogleData { m.payload.headers && m.payload.headers .filter(h => h.name === 'To' || h.name === 'From') - .map(h => h.value!) // eslint-disable-line @typescript-eslint/no-non-null-assertion + .map(h => h.value) .filter(h => !!h) .join(',') ); diff --git a/test/source/mock/google/google-endpoints.ts b/test/source/mock/google/google-endpoints.ts index 28298338799..94c52e0d72e 100644 --- a/test/source/mock/google/google-endpoints.ts +++ b/test/source/mock/google/google-endpoints.ts @@ -2,12 +2,12 @@ import { HttpClientErr, Status } from '../lib/api'; import Parse, { ParseMsgResult } from '../../util/parse'; -import { isDelete, isGet, isPost, isPut, parseResourceId } from '../lib/mock-util'; +import { isDelete, isGet, isPost, isPut, parsePort, parseResourceId } from '../lib/mock-util'; import { GoogleData } from './google-data'; import { HandlersDefinition } from '../all-apis-mock'; import { AddressObject, ParsedMail } from 'mailparser'; import { TestBySubjectStrategyContext } from './strategies/send-message-strategy'; -import { UnsuportableStrategyError } from './strategies/strategy-base'; +import { UnsupportableStrategyError } from './strategies/strategy-base'; import { oauth } from '../lib/oauth'; import { Util } from '../../util'; @@ -56,7 +56,7 @@ export const mockGoogleEndpoints: HandlersDefinition = { } else if (!proceed) { return oauth.renderText('redirect with proceed=true to continue'); } else { - return oauth.successResult(login_hint, state, scope); + return oauth.successResult(parsePort(req), login_hint, state, scope); } } throw new HttpClientErr(`Method not implemented for ${req.url}: ${req.method}`); @@ -223,8 +223,7 @@ export const mockGoogleEndpoints: HandlersDefinition = { if (isGet(req)) { const id = parseResourceId(req.url!); // eslint-disable-line @typescript-eslint/no-non-null-assertion const data = await GoogleData.withInitializedData(acct); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - if (req.url!.includes('/attachments/')) { + if (req.url?.includes('/attachments/')) { const attachment = data.getAttachment(id); if (attachment) { return attachment; @@ -255,8 +254,7 @@ export const mockGoogleEndpoints: HandlersDefinition = { throw new HttpClientErr(`Method not implemented for ${req.url}: ${req.method}`); }, '/gmail/v1/users/me/threads/?': async ({ query: { format } }, req) => { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - if (req.url!.match(/\/modify$/)) { + if (req.url?.match(/\/modify$/)) { return {}; } const acct = oauth.checkAuthorizationHeaderWithAccessToken(req.headers.authorization); @@ -281,9 +279,9 @@ export const mockGoogleEndpoints: HandlersDefinition = { const id = `msg_id_${Util.lousyRandom()}`; try { const testingStrategyContext = new TestBySubjectStrategyContext(parseResult.mimeMsg.subject || ''); - await testingStrategyContext.test(parseResult, id); + await testingStrategyContext.test(parseResult, id, parsePort(req)); } catch (e) { - if (!(e instanceof UnsuportableStrategyError)) { + if (!(e instanceof UnsupportableStrategyError)) { // No such strategy for test throw e; // todo - should start throwing unsupported test strategies too, else changing subject will cause incomplete testing // todo - should stop calling it "strategy", better just "SentMessageTest" or similar @@ -361,8 +359,7 @@ const parseMultipartDataAsMimeMsg = async (multipartData: string): Promise { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const inReplyToMessageId = mimeMsg.headers.get('in-reply-to') ? mimeMsg.headers.get('in-reply-to')!.toString() : ''; + const inReplyToMessageId = mimeMsg.headers.get('in-reply-to') ? mimeMsg.headers.get('in-reply-to')?.toString() : ''; if (threadId) { const messages = (await GoogleData.withInitializedData(acct)).getMessagesByThread(threadId); if (!messages || !messages.length) { diff --git a/test/source/mock/google/strategies/send-message-strategy.ts b/test/source/mock/google/strategies/send-message-strategy.ts index 7f85cb5f091..2a79d5f57e1 100644 --- a/test/source/mock/google/strategies/send-message-strategy.ts +++ b/test/source/mock/google/strategies/send-message-strategy.ts @@ -2,7 +2,7 @@ import * as forge from 'node-forge'; import { AddressObject, StructuredHeader } from 'mailparser'; -import { ITestMsgStrategy, UnsuportableStrategyError } from './strategy-base.js'; +import { ITestMsgStrategy, UnsupportableStrategyError } from './strategy-base.js'; import { Buf } from '../../../core/buf'; import { Config } from '../../../util'; import { expect } from 'chai'; @@ -70,15 +70,15 @@ class PwdEncryptedMessageWithFlowCryptComApiTestStrategy implements ITestMsgStra } class PwdEncryptedMessageWithFesIdTokenTestStrategy implements ITestMsgStrategy { - public test = async (parseResult: ParseMsgResult, id: string) => { + public test = async (parseResult: ParseMsgResult, id: string, port: string) => { const mimeMsg = parseResult.mimeMsg; - const expectedSenderEmail = 'user@standardsubdomainfes.localhost:8001'; + const expectedSenderEmail = `user@standardsubdomainfes.localhost:${port}`; expect(mimeMsg.from!.text).to.equal(`First Last <${expectedSenderEmail}>`); - if (mimeMsg.text?.includes('http://fes.standardsubdomainfes.localhost:8001/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID')) { + if (mimeMsg.text?.includes(`http://fes.standardsubdomainfes.localhost:${port}/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID`)) { expect((mimeMsg.to as AddressObject).text).to.equal('Mr To '); expect(mimeMsg.cc).to.be.an.undefined; expect(mimeMsg.bcc).to.be.an.undefined; - } else if (mimeMsg.text?.includes('http://fes.standardsubdomainfes.localhost:8001/message/FES-MOCK-MESSAGE-FOR-BCC@EXAMPLE.COM-ID')) { + } else if (mimeMsg.text?.includes(`http://fes.standardsubdomainfes.localhost:${port}/message/FES-MOCK-MESSAGE-FOR-BCC@EXAMPLE.COM-ID`)) { expect((mimeMsg.to as AddressObject).text).to.equal('Mr Bcc '); expect(mimeMsg.cc).to.be.an.undefined; expect(mimeMsg.bcc).to.be.an.undefined; @@ -93,11 +93,11 @@ class PwdEncryptedMessageWithFesIdTokenTestStrategy implements ITestMsgStrategy } class PwdEncryptedMessageWithFesPubkeyRecipientInBccTestStrategy implements ITestMsgStrategy { - public test = async (parseResult: ParseMsgResult, id: string) => { + public test = async (parseResult: ParseMsgResult, id: string, port: string) => { const mimeMsg = parseResult.mimeMsg; - const expectedSenderEmail = 'user3@standardsubdomainfes.localhost:8001'; + const expectedSenderEmail = `user3@standardsubdomainfes.localhost:${port}`; expect(mimeMsg.from!.text).to.equal(`First Last <${expectedSenderEmail}>`); - if (mimeMsg.text?.includes('http://fes.standardsubdomainfes.localhost:8001/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID')) { + if (mimeMsg.text?.includes(`http://fes.standardsubdomainfes.localhost:${port}/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID`)) { expect(mimeMsg.text!).to.include(`${expectedSenderEmail} has sent you a password-encrypted email`); expect(mimeMsg.text!).to.include('Follow this link to open it'); expect((mimeMsg.to as AddressObject).text).to.equal('to@example.com'); @@ -116,16 +116,16 @@ class PwdEncryptedMessageWithFesPubkeyRecipientInBccTestStrategy implements ITes expect((mimeMsg.bcc as AddressObject).text).to.equal('flowcrypt.compatibility@gmail.com'); expect(mimeMsg.cc).to.be.an.undefined; expect(mimeMsg.to).to.be.an.undefined; - expect((mimeMsg.headers.get('reply-to') as AddressObject).text).to.equal('First Last , to@example.com'); + expect((mimeMsg.headers.get('reply-to') as AddressObject).text).to.equal(`First Last , to@example.com`); } await new SaveMessageInStorageStrategy().test(parseResult, id); }; } class PwdEncryptedMessageWithFesReplyBadRequestTestStrategy implements ITestMsgStrategy { - public test = async (parseResult: ParseMsgResult, id: string) => { + public test = async (parseResult: ParseMsgResult, id: string, port: string) => { const mimeMsg = parseResult.mimeMsg; - const expectedSenderEmail = 'user4@standardsubdomainfes.localhost:8001'; + const expectedSenderEmail = `user4@standardsubdomainfes.localhost:${port}`; expect(mimeMsg.from!.text).to.equal(`First Last <${expectedSenderEmail}>`); const to = parsedMailAddressObjectAsArray(mimeMsg.to) .concat(parsedMailAddressObjectAsArray(mimeMsg.cc)) @@ -147,18 +147,18 @@ class PwdEncryptedMessageWithFesReplyBadRequestTestStrategy implements ITestMsgS } class PwdEncryptedMessageWithFesReplyRenderingTestStrategy implements ITestMsgStrategy { - public test = async (parseResult: ParseMsgResult, id: string) => { + public test = async (parseResult: ParseMsgResult, id: string, port: string) => { const mimeMsg = parseResult.mimeMsg; - const expectedSenderEmail = 'user2@standardsubdomainfes.localhost:8001'; + const expectedSenderEmail = `user2@standardsubdomainfes.localhost:${port}`; expect(mimeMsg.from!.text).to.equal(`First Last <${expectedSenderEmail}>`); - if (mimeMsg.text?.includes('http://fes.standardsubdomainfes.localhost:8001/message/FES-MOCK-MESSAGE-FOR-SENDER@DOMAIN.COM-ID')) { + if (mimeMsg.text?.includes(`http://fes.standardsubdomainfes.localhost:${port}/message/FES-MOCK-MESSAGE-FOR-SENDER@DOMAIN.COM-ID`)) { expect(mimeMsg.text!).to.include(`${expectedSenderEmail} has sent you a password-encrypted email`); expect(mimeMsg.text!).to.include('Follow this link to open it'); expect((mimeMsg.to as AddressObject).text).to.equal('sender@domain.com'); expect(mimeMsg.cc).to.be.an.undefined; expect(mimeMsg.bcc).to.be.an.undefined; expect(mimeMsg.headers.get('reply-to')).to.be.an.undefined; - } else if (mimeMsg.text?.includes('http://fes.standardsubdomainfes.localhost:8001/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID')) { + } else if (mimeMsg.text?.includes(`http://fes.standardsubdomainfes.localhost:${port}/message/FES-MOCK-MESSAGE-FOR-TO@EXAMPLE.COM-ID`)) { expect(mimeMsg.text!).to.include(`${expectedSenderEmail} has sent you a password-encrypted email`); expect(mimeMsg.text!).to.include('Follow this link to open it'); expect((mimeMsg.to as AddressObject).text).to.equal('to@example.com'); @@ -178,7 +178,7 @@ class PwdEncryptedMessageWithFesReplyRenderingTestStrategy implements ITestMsgSt expect(mimeMsg.cc).to.be.an.undefined; expect(mimeMsg.bcc).to.be.an.undefined; expect((mimeMsg.headers.get('reply-to') as AddressObject).text).to.equal( - 'First Last , sender@domain.com, to@example.com' + `First Last , sender@domain.com, to@example.com` ); } await new SaveMessageInStorageStrategy().test(parseResult, id); @@ -249,7 +249,7 @@ class PlainTextMessageTestStrategy implements ITestMsgStrategy { } class NoopTestStrategy implements ITestMsgStrategy { - public test = async () => {}; // eslint-disable-line @typescript-eslint/no-empty-function, no-empty-function + public test = async () => {}; // eslint-disable-line @typescript-eslint/no-empty-function } class IncludeQuotedPartTestStrategy implements ITestMsgStrategy { @@ -411,11 +411,11 @@ export class TestBySubjectStrategyContext { } else if (subject.includes('Re: FROM: flowcrypt.compatibility@gmail.com, TO: flowcrypt.compatibility@gmail.com + vladimir@flowcrypt.com')) { this.strategy = new NoopTestStrategy(); } else { - throw new UnsuportableStrategyError(`There isn't any strategy for this subject: ${subject}`); + throw new UnsupportableStrategyError(`There isn't any strategy for this subject: ${subject}`); } } - public test = async (parseResult: ParseMsgResult, id: string) => { - await this.strategy.test(parseResult, id); + public test = async (parseResult: ParseMsgResult, id: string, port: string) => { + await this.strategy.test(parseResult, id, port); }; } diff --git a/test/source/mock/google/strategies/strategy-base.ts b/test/source/mock/google/strategies/strategy-base.ts index f830882b012..a8e1e590350 100644 --- a/test/source/mock/google/strategies/strategy-base.ts +++ b/test/source/mock/google/strategies/strategy-base.ts @@ -3,7 +3,7 @@ import { ParseMsgResult } from '../../../util/parse'; export interface ITestMsgStrategy { - test(parseResult: ParseMsgResult, id: string): Promise; + test(parseResult: ParseMsgResult, id: string, port: string): Promise; } -export class UnsuportableStrategyError extends Error {} +export class UnsupportableStrategyError extends Error {} diff --git a/test/source/mock/key-manager/key-manager-endpoints.ts b/test/source/mock/key-manager/key-manager-endpoints.ts index 88f7cc7ebb3..990d0bb144f 100644 --- a/test/source/mock/key-manager/key-manager-endpoints.ts +++ b/test/source/mock/key-manager/key-manager-endpoints.ts @@ -2,7 +2,7 @@ import { HttpClientErr, Status } from '../lib/api'; import { HandlersDefinition } from '../all-apis-mock'; -import { isPut, isGet } from '../lib/mock-util'; +import { isPut, isGet, parsePort } from '../lib/mock-util'; import { oauth } from '../lib/oauth'; import { Dict } from '../../core/common'; import { expect } from 'chai'; @@ -218,7 +218,8 @@ export const mockKeyManagerEndpoints: HandlersDefinition = { '/flowcrypt-email-key-manager/v1/keys/private': async ({ body }, req) => { const acctEmail = oauth.checkAuthorizationHeaderWithIdToken(req.headers.authorization); if (isGet(req)) { - if (acctEmail === 'wkd@google.mock.localhost:8001') { + const port = parsePort(req); + if (acctEmail === `wkd@google.mock.localhost:${port}`) { return { privateKeys: [{ decryptedPrivateKey: testConstants.wkdAtgooglemockflowcryptlocalcom8001Private }] }; } if (acctEmail === 'get.key@key-manager-autogen.flowcrypt.test') { diff --git a/test/source/mock/lib/api.ts b/test/source/mock/lib/api.ts index cab9c494dec..4eb4987550e 100644 --- a/test/source/mock/lib/api.ts +++ b/test/source/mock/lib/api.ts @@ -84,15 +84,17 @@ export class Api { }); } - public listen = (port: number, host = '127.0.0.1', maxMb = 100): Promise => { + public listen = (host = '127.0.0.1', maxMb = 100): Promise => { return new Promise((resolve, reject) => { try { this.maxRequestSizeMb = maxMb; this.maxRequestSizeBytes = maxMb * 1024 * 1024; - this.server.listen(port, host); + // node.js selects random available port when port = 0 + this.server.listen(0, host); this.server.on('listening', () => { const address = this.server.address(); - const msg = `${this.apiName} listening on ${typeof address === 'object' && address ? address.port : address}`; + const port = typeof address === 'object' && address ? address.port : undefined; + const msg = `${this.apiName} listening on ${port}`; console.log(msg); resolve(); }); @@ -241,7 +243,7 @@ export class Api { private throttledResponse = async (response: http.ServerResponse, data: Buffer) => { // If google oauth2 login, then redirect to url - if (/^https:\/\/google\.localhost:8001\/robots\.txt/.test(data.toString())) { + if (/^https:\/\/google\.localhost:[0-9]+\/robots\.txt/.test(data.toString())) { response.writeHead(302, { Location: data.toString() }); // eslint-disable-line @typescript-eslint/naming-convention } else { const chunkSize = 100 * 1024; diff --git a/test/source/mock/lib/mock-util.ts b/test/source/mock/lib/mock-util.ts index 328561bf6df..e66fb9a4af7 100644 --- a/test/source/mock/lib/mock-util.ts +++ b/test/source/mock/lib/mock-util.ts @@ -7,4 +7,6 @@ export const isPost = (r: IncomingMessage) => r.method === 'POST'; export const isPut = (r: IncomingMessage) => r.method === 'PUT'; export const isDelete = (r: IncomingMessage) => r.method === 'DELETE'; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion +export const parsePort = (r: IncomingMessage) => r.headers.host!.split(':')[1]; +// eslint-disable-next-line @typescript-eslint/no-non-null-assertion export const parseResourceId = (url: string) => url.match(/\/([a-zA-Z0-9\-_]+)(\?|$)/)![1]; diff --git a/test/source/mock/lib/oauth.ts b/test/source/mock/lib/oauth.ts index 853778f53e6..ed80035bf57 100644 --- a/test/source/mock/lib/oauth.ts +++ b/test/source/mock/lib/oauth.ts @@ -10,7 +10,6 @@ const authURL = 'https://localhost:8001'; export class OauthMock { public clientId = '717284730244-5oejn54f10gnrektjdc4fv4rbic1bj1p.apps.googleusercontent.com'; public expiresIn = 2 * 60 * 60; // 2hrs in seconds - public redirectUri = 'https://google.localhost:8001/robots.txt'; private authCodesByAcct: { [acct: string]: string } = {}; private scopesByAccessToken: { [token: string]: string } = {}; @@ -24,7 +23,7 @@ export class OauthMock { return this.htmlPage(text, text); }; - public successResult = (acct: string, state: string, scope: string) => { + public successResult = (port: string, acct: string, state: string, scope: string) => { const authCode = `mock-auth-code-${Str.sloppyRandom(4)}-${acct.replace(/[^a-z0-9]+/g, '')}`; const refreshToken = `mock-refresh-token-${Str.sloppyRandom(4)}-${acct.replace(/[^a-z0-9]+/g, '')}`; const accessToken = `mock-access-token-${Str.sloppyRandom(4)}-${acct.replace(/[^a-z0-9]+/g, '')}`; @@ -33,7 +32,7 @@ export class OauthMock { this.accessTokenByRefreshToken[refreshToken] = accessToken; this.acctByAccessToken[accessToken] = acct; this.scopesByAccessToken[accessToken] = `${this.scopesByAccessToken[accessToken] ?? ''} ${scope}`; - const url = new URL(this.redirectUri); + const url = new URL(`https://google.localhost:${port}/robots.txt`); url.searchParams.set('code', authCode); url.searchParams.set('scope', scope); // return invalid state for test.invalid.csrf@gmail.com to check invalid csrf login diff --git a/test/source/test.ts b/test/source/test.ts index 4ddf208fe3a..36ad389e52f 100644 --- a/test/source/test.ts +++ b/test/source/test.ts @@ -1,10 +1,12 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ -import * as ava from 'ava'; +import test, { Implementation } from 'ava'; +import { promisify } from 'util'; +import { exec } from 'child_process'; import { AvaContext, getDebugHtmlAtts, minutes, standaloneTestTimeout } from './tests/tooling'; import { BrowserHandle, BrowserPool } from './browser'; -import { Config, Util, getParsedCliParams } from './util'; +import { Util, getParsedCliParams } from './util'; import { BrowserRecipe } from './tests/tooling/browser-recipe'; import { defineComposeTests } from './tests/compose'; @@ -16,18 +18,17 @@ import { defineSettingsTests } from './tests/settings'; import { defineSetupTests } from './tests/setup'; import { defineUnitNodeTests } from './tests/unit-node'; import { defineUnitBrowserTests } from './tests/unit-browser'; -import { mock } from './mock'; import { mockBackendData } from './mock/backend/backend-endpoints'; import { TestUrls } from './browser/test-urls'; import { mkdirSync, realpathSync, writeFileSync } from 'fs'; -// import fileSize from 'filesize'; +import { startAllApisMock } from './mock/all-apis-mock'; export const { testVariant, testGroup, oneIfNotPooled, buildDir, isMock } = getParsedCliParams(); export const internalTestState = { expectIntentionalErrReport: false }; // updated when a particular test that causes an error is run const DEBUG_BROWSER_LOG = false; // set to true to print / export information from browser -const DEBUG_MOCK_LOG = false; // se to true to print mock server logs +const DEBUG_MOCK_LOG = false; // set to true to print mock server logs -process.setMaxListeners(60); +process.setMaxListeners(0); /* eslint-disable @typescript-eslint/naming-convention */ const consts = { @@ -48,86 +49,98 @@ consts.PROMISE_TIMEOUT_OVERALL = new Promise((resolve, reject) => setTimeout(() export type Consts = typeof consts; export type CommonAcct = 'compatibility' | 'compose' | 'ci.tests.gmail'; -const browserPool = new BrowserPool(consts.POOL_SIZE, 'browserPool', false, buildDir, isMock, undefined, undefined, consts.IS_LOCAL_DEBUG); -let closeMockApi: () => Promise; +const asyncExec = promisify(exec); +const browserPool = new BrowserPool(consts.POOL_SIZE, 'browserPool', buildDir, isMock, undefined, undefined, consts.IS_LOCAL_DEBUG); const mockApiLogs: string[] = []; -ava.default.before('set config and mock api', async t => { - standaloneTestTimeout(t, consts.TIMEOUT_EACH_RETRY, t.title); - Config.extensionId = await browserPool.getExtensionId(t); - console.info(`Extension url: chrome-extension://${Config.extensionId}`); - if (isMock) { - const mockApi = await mock(line => { - if (DEBUG_MOCK_LOG) { - console.log(line); - } - mockApiLogs.push(line); - }); - closeMockApi = mockApi.close; - } - t.pass(); +test.beforeEach('set timeout', async t => { + t.timeout(consts.TIMEOUT_EACH_RETRY); }); const testWithBrowser = ( acct: CommonAcct | undefined, cb: (t: AvaContext, browser: BrowserHandle) => Promise, flag?: 'FAILING' -): ava.Implementation => { +): Implementation => { return async (t: AvaContext) => { - await browserPool.withNewBrowserTimeoutAndRetry( - async (t, browser) => { - const start = Date.now(); - if (acct) { - await BrowserRecipe.setUpCommonAcct(t, browser, acct); - } - await cb(t, browser); - if (DEBUG_BROWSER_LOG) { - try { - const page = await browser.newPage(t, TestUrls.extension('chrome/dev/ci_unit_test.htm')); - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return - const items = (await page.target.evaluate(() => (window as any).Debug.readDatabase())) as { - input: unknown; - output: unknown; - }[]; - for (let i = 0; i < items.length; i++) { - const item = items[i]; - const input = JSON.stringify(item.input); - const output = JSON.stringify(item.output, undefined, 2); - const file = `./test/tmp/${t.title}-${i}.txt`; - writeFileSync(file, `in: ${input}\n\nout: ${output}`); - t.log(`browser debug written to file: ${file}`); - } - } catch (e) { - t.log(`Error reading debug messages: ${e}`); + let closeMockApi: (() => Promise) | undefined; + if (isMock) { + const mockApi = await startMockApiAndCopyBuild(t); + closeMockApi = mockApi.close; + } + try { + await browserPool.withNewBrowserTimeoutAndRetry( + async (t, browser) => { + const start = Date.now(); + if (acct) { + await BrowserRecipe.setUpCommonAcct(t, browser, acct); } - } - t.log(`run time: ${Math.ceil((Date.now() - start) / 1000)}s`); - }, - t, - consts, - flag - ); - t.pass(); + await cb(t, browser); + if (DEBUG_BROWSER_LOG) { + await saveBrowserLog(t, browser); + } + t.log(`run time: ${Math.ceil((Date.now() - start) / 1000)}s`); + }, + t, + consts, + flag + ); + + t.pass(); + } finally { + if (closeMockApi) { + await closeMockApi(); + } + } }; }; -export type TestWithBrowser = typeof testWithBrowser; +const startMockApiAndCopyBuild = async (t: AvaContext) => { + const mockApi = await startAllApisMock(line => { + if (DEBUG_MOCK_LOG) { + console.log(line); + } + mockApiLogs.push(line); + }).catch(e => { + console.error(e); + process.exit(1); + }); + const address = mockApi.server.address(); + if (typeof address === 'object' && address) { + const result = await asyncExec(`sh ./scripts/config-mock-build.sh ${buildDir} ${address.port}`); -ava.default.after.always('close browsers', async t => { - standaloneTestTimeout(t, consts.TIMEOUT_SHORT, t.title); - await browserPool.close(); - t.pass(); -}); + t.extensionDir = result.stdout; + t.urls = new TestUrls(await browserPool.getExtensionId(t), address.port); + } else { + t.log('Failed to get mock build address'); + } + return mockApi; +}; -if (isMock) { - ava.default.after.always('close mock api', async t => { - standaloneTestTimeout(t, consts.TIMEOUT_SHORT, t.title); - closeMockApi().catch(t.log); - t.pass(); - }); -} +const saveBrowserLog = async (t: AvaContext, browser: BrowserHandle) => { + try { + const page = await browser.newPage(t, t.urls?.extension('chrome/dev/ci_unit_test.htm')); + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return + const items = (await page.target.evaluate(() => (window as any).Debug.readDatabase())) as { + input: unknown; + output: unknown; + }[]; + for (let i = 0; i < items.length; i++) { + const item = items[i]; + const input = JSON.stringify(item.input); + const output = JSON.stringify(item.output, undefined, 2); + const file = `./test/tmp/${t.title}-${i}.txt`; + writeFileSync(file, `in: ${input}\n\nout: ${output}`); + t.log(`browser debug written to file: ${file}`); + } + } catch (e) { + t.log(`Error reading debug messages: ${e}`); + } +}; + +export type TestWithBrowser = typeof testWithBrowser; -ava.default.after.always('evaluate Catch.reportErr errors', async t => { +test.after.always('evaluate Catch.reportErr errors', async t => { if (!isMock || testGroup !== 'STANDARD-GROUP') { // can only collect reported errs when running with a mocked api t.pass(); @@ -141,10 +154,8 @@ ava.default.after.always('evaluate Catch.reportErr errors', async t => { // below for test "get.updating.key@key-manager-choose-passphrase-forbid-storing.flowcrypt.test - automatic update of key found on key manager" .filter( e => - ![ - 'BrowserMsg(processAndStoreKeysFromEkmLocally) sendRawResponse::Error: Some keys could not be parsed', - 'BrowserMsg(ajax) Bad Request: 400 when GET-ing https://localhost:8001/flowcrypt-email-key-manager/v1/keys/private (no body): -> RequestTimeout', - ].includes(e.message) + e.message !== 'BrowserMsg(processAndStoreKeysFromEkmLocally) sendRawResponse::Error: Some keys could not be parsed' && + !e.message.match(/BrowserMsg\(ajax\) Bad Request: 400 when GET-ing https:\/\/localhost:\d+\/flowcrypt-email-key-manager/) ) // below for test "user4@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal - a send fails with gateway update error" .filter(e => !e.message.includes('Test error')) @@ -154,7 +165,7 @@ ava.default.after.always('evaluate Catch.reportErr errors', async t => { .filter(e => !e.trace.includes('-1 when GET-ing https://openpgpkey.flowcrypt.com')) // below for "test allows to retry public key search when attester returns error" .filter( - e => !e.message.includes('Error: Internal Server Error: 500 when GET-ing https://localhost:8001/attester/pub/attester.return.error@flowcrypt.test') + e => !e.message.match(/Error: Internal Server Error: 500 when GET-ing https:\/\/localhost:\d+\/attester\/pub\/attester.return.error@flowcrypt.test/) ); const foundExpectedErr = usefulErrors.find(re => re.message === `intentional error for debugging`); const foundUnwantedErrs = usefulErrors.filter(re => re.message !== `intentional error for debugging` && !re.message.includes('traversal forbidden')); @@ -178,7 +189,7 @@ ava.default.after.always('evaluate Catch.reportErr errors', async t => { } }); -ava.default.after.always('send debug info if any', async t => { +test.after.always('send debug info if any', async t => { console.info('send debug info - deciding'); const failRnd = Util.lousyRandom(); const testId = `FlowCrypt Browser Extension ${testVariant} ${failRnd}`; diff --git a/test/source/tests/compose.ts b/test/source/tests/compose.ts index 0c95ebc3122..afc9d6ceebc 100644 --- a/test/source/tests/compose.ts +++ b/test/source/tests/compose.ts @@ -1,6 +1,6 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ -import * as ava from 'ava'; +import test from 'ava'; import { BrowserHandle, Controllable, ControllableFrame, ControllablePage } from './../browser'; import { Config, Util } from './../util'; @@ -14,7 +14,6 @@ import { OauthPageRecipe } from './page-recipe/oauth-page-recipe'; import { PageRecipe } from './page-recipe/abstract-page-recipe'; import { SettingsPageRecipe } from './page-recipe/settings-page-recipe'; import { protonMailCompatKey, somePubkey } from './../mock/attester/attester-endpoints'; -import { TestUrls } from './../browser/test-urls'; import { TestVariant } from './../util'; import { TestWithBrowser } from './../test'; import { expect } from 'chai'; @@ -28,7 +27,7 @@ import { ElementHandle, Page } from 'puppeteer'; export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: TestWithBrowser) => { if (testVariant !== 'CONSUMER-LIVE-GMAIL') { - ava.default( + test( 'compose - send an encrypted message to a legacy pwd recipient and a pubkey recipient', testWithBrowser('compatibility', async (t, browser) => { const acct = 'flowcrypt.compatibility@gmail.com'; @@ -44,7 +43,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - check for sender [flowcrypt.compatibility@gmail.com] from a password-protected email', testWithBrowser('compatibility', async (t, browser) => { const senderEmail = 'flowcrypt.compatibility@gmail.com'; @@ -58,7 +57,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - check for sender [flowcryptcompatibility@gmail.com] (alias) from a password-protected email', testWithBrowser('compatibility', async (t, browser) => { const senderEmail = 'flowcryptcompatibility@gmail.com'; @@ -72,7 +71,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - check for sender [ci.tests.gmail@flowcrypt.test] from a password-protected email', testWithBrowser('ci.tests.gmail', async (t, browser) => { const senderEmail = 'ci.tests.gmail@flowcrypt.test'; @@ -85,10 +84,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - restore compose window size by clicking its header', testWithBrowser('compatibility', async (t, browser) => { - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('flowcrypt.compatibility@gmail.com')); + const inboxPage = await browser.newExtensionInboxPage(t, 'flowcrypt.compatibility@gmail.com'); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); const initialComposeFrameHeight = await inboxPage.getOuterHeight('iframe'); await composeFrame.waitAll('#section_header'); @@ -101,7 +100,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - trying to send PWD encrypted message with pass phrase - should show err', testWithBrowser('ci.tests.gmail', async (t, browser) => { const acctEmail = 'ci.tests.gmail@flowcrypt.test'; @@ -124,7 +123,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }); const forgottenPassphrase = 'this passphrase is forgotten'; await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, testConstants.testKeyMultipleSmimeCEA2D53BB9D24871, forgottenPassphrase, {}, false); - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox(acctEmail)); + const inboxPage = await browser.newExtensionInboxPage(t, acctEmail); await InboxPageRecipe.finishSessionOnInboxPage(inboxPage); await inboxPage.close(); await composePage.waitAndType('@input-password', forgottenPassphrase); @@ -136,7 +135,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'user@key-manager-disabled-password-message.flowcrypt.test - disabled flowcrypt hosted password protected messages', testWithBrowser(undefined, async (t, browser) => { const acct = 'user@key-manager-disabled-password-message.flowcrypt.test'; @@ -153,13 +152,13 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - signed with entered pass phrase + will remember pass phrase in session', testWithBrowser('ci.tests.gmail', async (t, browser) => { const k = Config.key('ci.tests.gmail'); - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('ci.tests.gmail@flowcrypt.test')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'ci.tests.gmail@flowcrypt.test'); await SettingsPageRecipe.forgetAllPassPhrasesInStorage(settingsPage, k.passphrase); - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg(composeFrame, { to: 'human@flowcrypt.com' }, 'sign with entered pass phrase', undefined, { encrypt: false, @@ -183,7 +182,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - can load contact based on name', testWithBrowser('ci.tests.gmail', async (t, browser) => { // works on first search @@ -199,7 +198,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - can load contact based on name different from email', testWithBrowser('ci.tests.gmail', async (t, browser) => { // works on the first search @@ -213,7 +212,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - should not show contacts for empty #input_to', testWithBrowser('ci.tests.gmail', async (t, browser) => { // works on the first search @@ -232,7 +231,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `compose - can choose found contact`, testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -254,23 +253,23 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `compose - recipients are properly ordered`, testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); await composePage.page.setViewport({ width: 540, height: 606 }); - await ComposePageRecipe.fillMsg(composePage, { to: 'recip1@corp.co', cc: 'сс1@corp.co', bcc: 'bсс1@corp.co' }, 'recipients are properly ordered'); + await ComposePageRecipe.fillMsg(composePage, { to: 'recip1@corp.co', cc: 'cc1@corp.co', bcc: 'bcc1@corp.co' }, 'recipients are properly ordered'); await composePage.waitAndType(`@input-to`, 'recip2@corp.co'); await composePage.waitAndType(`@input-bcc`, 'bcc2@corp.co'); await composePage.waitAndFocus('@input-body'); await composePage.waitTillGone('@spinner'); const emailPreview = await composePage.waitAny('@recipients-preview'); const recipients = await PageRecipe.getElementPropertyJson(emailPreview, 'textContent'); - expect(recipients).to.eq(['recip1@corp.co', 'recip2@corp.co', 'сс1@corp.co', 'bсс1@corp.co', '1 more'].join('')); + expect(recipients).to.eq(['recip1@corp.co', 'recip2@corp.co', 'cc1@corp.co', 'bcc1@corp.co', '1 more'].join('')); }) ); - ava.default( + test( `compose - auto include pubkey when our key is not available on Wkd`, testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -287,10 +286,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `compose - auto include pubkey is inactive when our key is available on Wkd`, testWithBrowser(undefined, async (t, browser) => { - const acct = 'wkd@google.mock.localhost:8001'; + const acct = `wkd@google.mock.localhost:${t.urls?.port}`; const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, acct); await SetupPageRecipe.autoSetupWithEKM(settingsPage); const composePage = await ComposePageRecipe.openStandalone(t, browser, acct); @@ -307,7 +306,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `compose - freshly loaded pubkey`, testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -316,7 +315,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - recipient pasted including name', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -325,7 +324,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - nopgp', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -334,7 +333,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - from alias', testWithBrowser('compatibility', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility'); @@ -344,7 +343,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - with attachments + nopgp', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -356,7 +355,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - signed message', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -367,10 +366,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - settings - manually copied pubkey', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const dbPage = await browser.newPage(t, TestUrls.extension('chrome/dev/ci_unit_test.htm')); + const dbPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); // add a contact containing 2 pubkeys to the storage await dbPage.page.evaluate( async (pubkeys: string[]) => { @@ -383,7 +382,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }, [testConstants.abcddfTestComPubkey, testConstants.abcdefTestComPubkey] ); - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg(composeFrame, { to: 'manualcopypgp@flowcrypt.com' }, 'manual copied key'); await composeFrame.waitAndClick('@action-open-add-pubkey-dialog', { delay: 1 }); @@ -416,10 +415,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - keyboard - Ctrl+Enter sends message', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await composeFrame.target.evaluateHandle(() => (document.querySelector('#section_compose') as HTMLElement).dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', ctrlKey: true })) @@ -428,10 +427,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - keyboard - Opening & changing composer send btn popover using keyboard', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await composeFrame.waitAndFocus('@action-show-options-popover'); await inboxPage.press('Enter'); @@ -441,10 +440,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - keyboard - Attaching file using keyboard', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await composeFrame.waitAndFocus('@action-attach-files'); // Set up the Promise *before* the file chooser is launched @@ -455,7 +454,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply - old gmail threadId fmt', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&threadId=16841ce0ce5cb74d&replyMsgId=16841ce0ce5cb74d'; @@ -469,7 +468,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply - thread id does not exist', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&threadId=16804894591b3a4b&replyMsgId=16804894591b3a4b'; @@ -483,7 +482,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - quote - can load quote from encrypted/text email', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=16b584ed95837510&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=16b584ed95837510'; @@ -511,7 +510,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - quote - can load quote from plain/text email', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=16402d6dc4342e7f&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___' + '&replyMsgId=16402d6dc4342e7f'; @@ -527,7 +526,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply - can load quote from plain/html email', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=16b36861a890bb26&skipClickPrompt=___cu_false___' + '&ignoreDraft=___cu_false___&replyMsgId=16b36861a890bb26'; @@ -553,7 +552,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply - can load quote from encrypted/html email', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=1663a65bbd73ce1a&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=1663a65bbd73ce1a'; @@ -576,7 +575,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te ); for (const inputMethod of ['mouse', 'keyboard']) { - ava.default( + test( `compose - reply - pass phrase dialog - dialog ok (${inputMethod})`, testWithBrowser('compatibility', async (t, browser) => { const pp = Config.key('flowcrypt.compatibility.1pp1').passphrase; @@ -610,7 +609,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `compose - reply - pass phrase dialog - dialog cancel (${inputMethod})`, testWithBrowser('compatibility', async (t, browser) => { const pp = Config.key('flowcrypt.compatibility.1pp1').passphrase; @@ -628,14 +627,14 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `compose - pass phrase dialog - dialog cancel (${inputMethod})`, testWithBrowser('ci.tests.gmail', async (t, browser) => { const k = Config.key('ci.tests.gmail'); const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acctEmail)); + const settingsPage = await browser.newExtensionSettingsPage(t, acctEmail); await SettingsPageRecipe.forgetAllPassPhrasesInStorage(settingsPage, k.passphrase); - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox(acctEmail)); + const inboxPage = await browser.newExtensionInboxPage(t, acctEmail); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg(composeFrame, { to: 'anyone@recipient.com' }, 'send signed-only message', undefined, { encrypt: false, @@ -652,16 +651,16 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `compose - non-primary pass phrase dialog - dialog cancel (${inputMethod})`, testWithBrowser('ci.tests.gmail', async (t, browser) => { const k = Config.key('ci.tests.gmail'); const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acctEmail)); + const settingsPage = await browser.newExtensionSettingsPage(t, acctEmail); const forgottenPassphrase = "i'll have to re-enter it"; await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, testConstants.testKeyMultipleSmimeCEA2D53BB9D24871, forgottenPassphrase, {}, true); await SettingsPageRecipe.forgetAllPassPhrasesInStorage(settingsPage, k.passphrase); - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox(acctEmail)); + const inboxPage = await browser.newExtensionInboxPage(t, acctEmail); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg(composeFrame, { to: 'smime@recipient.com' }, 'S/MIME message', undefined); await ComposePageRecipe.pastePublicKeyManually( @@ -682,16 +681,16 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te ); } // end of tests per inputMethod - ava.default( + test( `compose - signed and encrypted S/MIME message - pass phrase dialog`, testWithBrowser('ci.tests.gmail', async (t, browser) => { const k = Config.key('ci.tests.gmail'); const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acctEmail)); + const settingsPage = await browser.newExtensionSettingsPage(t, acctEmail); const forgottenPassphrase = "i'll have to re-enter it"; await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, testConstants.testKeyMultipleSmimeCEA2D53BB9D24871, forgottenPassphrase, {}, true); await SettingsPageRecipe.forgetAllPassPhrasesInStorage(settingsPage, k.passphrase); - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox(acctEmail)); + const inboxPage = await browser.newExtensionInboxPage(t, acctEmail); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg(composeFrame, { to: 'smime@recipient.com' }, t.title, undefined); await ComposePageRecipe.pastePublicKeyManually( @@ -711,7 +710,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply - signed message', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=15f7f5face7101db&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=15f7f5face7101db'; @@ -732,7 +731,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - forward - pgp/mime signed-only', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=15f7fc2919788f03&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=15f7fc2919788f03'; @@ -747,7 +746,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - standalone- hide/show btns after signing', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -761,7 +760,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - show no contact found result if there are no contacts', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -783,7 +782,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - CC&BCC new message', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -796,7 +795,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - check recipient validation after user inputs incorrect recipient', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -813,7 +812,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply - CC&BCC test reply', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=16ce2c965c75e5a6&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=16ce2c965c75e5a6'; @@ -833,7 +832,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - expired can still send', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -853,10 +852,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - revoked OpenPGP key', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const dbPage = await browser.newPage(t, TestUrls.extension('chrome/dev/ci_unit_test.htm')); + const dbPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); await dbPage.page.evaluate(async (pubkey: string) => { /* eslint-disable @typescript-eslint/no-explicit-any */ const db = await (window as any).ContactStore.dbOpen(); @@ -875,10 +874,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - externally revoked key', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const dbPage = await browser.newPage(t, TestUrls.extension('chrome/dev/ci_unit_test.htm')); + const dbPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); await dbPage.page.evaluate(async (pubkey: string) => { /* eslint-disable @typescript-eslint/no-explicit-any */ const db = await (window as any).ContactStore.dbOpen(); @@ -904,10 +903,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - nogpg and revoked recipients trigger both warnings', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const dbPage = await browser.newPage(t, TestUrls.extension('chrome/dev/ci_unit_test.htm')); + const dbPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); await dbPage.page.evaluate(async (pubkey: string) => { /* eslint-disable @typescript-eslint/no-explicit-any */ const db = await (window as any).ContactStore.dbOpen(); @@ -923,10 +922,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - nogpg and non-revoked recipients trigger nopgp warning only', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const dbPage = await browser.newPage(t, TestUrls.extension('chrome/dev/ci_unit_test.htm')); + const dbPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); await dbPage.page.evaluate(async (pubkey: string) => { /* eslint-disable @typescript-eslint/no-explicit-any */ const db = await (window as any).ContactStore.dbOpen(); @@ -943,10 +942,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - revoked recipients trigger revoked warning', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const dbPage = await browser.newPage(t, TestUrls.extension('chrome/dev/ci_unit_test.htm')); + const dbPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); await dbPage.page.evaluate(async (pubkey: string) => { /* eslint-disable @typescript-eslint/no-explicit-any */ const db = await (window as any).ContactStore.dbOpen(); @@ -963,10 +962,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - good recipients trigger no warning', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const dbPage = await browser.newPage(t, TestUrls.extension('chrome/dev/ci_unit_test.htm')); + const dbPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); await dbPage.page.evaluate(async (pubkey: string) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const db = await (window as any).ContactStore.dbOpen(); @@ -983,7 +982,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - loading drafts - new message, rendering cc/bcc and check if cc/bcc btns are hidden', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'draftId=draft-1'; @@ -1002,7 +1001,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - loading drafts - PKCS#7 encrypted draft', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.test.key.imported@gmail.com'; @@ -1025,7 +1024,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - loading drafts - PKCS#7 encrypted draft with forgotten non-primary pass phrase', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.test.key.imported@gmail.com'; @@ -1055,7 +1054,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te {}, false ); - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox(acctEmail) + '&labelId=DRAFT&debug=___cu_true___'); + const inboxPage = await browser.newPage(t, t.urls?.extensionInbox(acctEmail) + '&labelId=DRAFT&debug=___cu_true___'); await InboxPageRecipe.finishSessionOnInboxPage(inboxPage); const inboxTabId = await PageRecipe.getTabId(inboxPage); // send message from a different tab @@ -1083,7 +1082,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - check reply to multiple recipients issue', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=183ec175f060b2c2&skipClickPrompt=___cu_false___&replyMsgId=183ec175f060b2c2'; @@ -1101,7 +1100,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - change reply option while composing', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=183ec175f060b2c2&skipClickPrompt=___cu_false___&replyMsgId=183ec175f060b2c2'; @@ -1124,7 +1123,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - hide reply all option button for signle recipient', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=182263bf9f105adf&skipClickPrompt=___cu_false___&replyMsgId=182263bf9f105adf'; @@ -1139,7 +1138,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te ); // todo: load a draft encrypted by non-first key, enetering passphrase for it - ava.default( + test( 'compose - loading drafts - reply', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=16cfa9001baaac0a&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=16cfa9001baaac0a&draftId=draft-3'; @@ -1156,7 +1155,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - key-mismatch - standalone - key mismatch loading', testWithBrowser('compatibility', async (t, browser) => { const params = @@ -1176,7 +1175,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply all - TO/CC/BCC when replying all', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = `threadId=16d6a6c2d6ae618f&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=16d6a6c2d6ae618f`; @@ -1200,7 +1199,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - send new plain message', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -1212,7 +1211,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply - signed message with attachment - can be downloaded after send', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=15f7f5face7101db&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=15f7f5face7101db'; @@ -1244,7 +1243,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - enforce message signing when encrypting', testWithBrowser('compatibility', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility'); @@ -1262,7 +1261,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - send btn should be disabled while encrypting/sending', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -1276,7 +1275,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - load contacts through API', testWithBrowser('ci.tests.gmail', async (t, browser) => { let composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -1301,7 +1300,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - delete recipients with keyboard', testWithBrowser('compatibility', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility'); @@ -1329,7 +1328,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - enter recipient which is not in the contact list', testWithBrowser('compatibility', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility'); @@ -1343,7 +1342,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - new message, open footer', testWithBrowser('compatibility', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility'); @@ -1366,7 +1365,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - new message, Footer Mock Test', testWithBrowser('compatibility', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility'); @@ -1375,7 +1374,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - loading drafts - test tags in draft', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'draftId=draft-0'; @@ -1384,7 +1383,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - compose - test minimizing/maximizing', testWithBrowser('ci.tests.gmail', async (t, browser) => { const inboxPage = await browser.newPage(t, 'chrome/settings/inbox/inbox.htm?acctEmail=ci.tests.gmail%40flowcrypt.test'); @@ -1414,7 +1413,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - saving and rendering a draft with image', testWithBrowser('compatibility', async (t, browser) => { const imgBase64 = @@ -1438,7 +1437,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - leading tabs', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=16b584ed95837510&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=16b584ed95837510'; @@ -1455,7 +1454,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - RTL subject', testWithBrowser('compatibility', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility'); @@ -1468,7 +1467,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - saving and rendering a draft with RTL text (plain text)', testWithBrowser('compatibility', async (t, browser) => { let composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility'); @@ -1486,7 +1485,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - saving and rendering a draft with RTL text (rich text)', testWithBrowser('compatibility', async (t, browser) => { let composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility'); @@ -1503,28 +1502,28 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - sending and rendering encrypted message with image', testWithBrowser('compatibility', async (t, browser) => { await sendImgAndVerifyPresentInSentMsg(t, browser, 'encrypt'); }) ); - ava.default( + test( 'compose - sending and rendering signed message with image', testWithBrowser('compatibility', async (t, browser) => { await sendImgAndVerifyPresentInSentMsg(t, browser, 'sign'); }) ); - ava.default( + test( 'compose - sending and rendering plain message with image', testWithBrowser('compatibility', async (t, browser) => { await sendImgAndVerifyPresentInSentMsg(t, browser, 'plain'); }) ); - ava.default( + test( 'compose - sending a message encrypted with all keys of a recipient', testWithBrowser('compatibility', async (t, browser) => { const text = 'This message is encrypted with 2 keys of flowcrypt.compatibility'; @@ -1537,7 +1536,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te await ComposePageRecipe.sendAndClose(composePage); /* eslint-disable @typescript-eslint/no-non-null-assertion */ // get sent msg from mock - const sentMsg = (await GoogleData.withInitializedData('flowcrypt.compatibility@gmail.com')).searchMessagesBySubject(subject)[0]!; + const sentMsg = (await GoogleData.withInitializedData('flowcrypt.compatibility@gmail.com')).searchMessagesBySubject(subject)[0]; const message = sentMsg.payload!.body!.data!; const encrypted = message.match(/\-\-\-\-\-BEGIN PGP MESSAGE\-\-\-\-\-.*\-\-\-\-\-END PGP MESSAGE\-\-\-\-\-/s)![0]; /* eslint-enable @typescript-eslint/no-non-null-assertion */ @@ -1562,7 +1561,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - sending and rendering message with U+10000 code points', testWithBrowser('compatibility', async (t, browser) => { const rainbow = '\ud83c\udf08'; @@ -1572,7 +1571,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( "compose - sent message should't have version and comment based on ClientConfiguration", testWithBrowser(undefined, async (t, browser) => { const acct = 'has.pub@client-configuration-test.flowcrypt.test'; @@ -1589,7 +1588,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te await ComposePageRecipe.sendAndClose(composePage); /* eslint-disable @typescript-eslint/no-non-null-assertion */ // get sent msg from mock - const sentMsg = (await GoogleData.withInitializedData(acct)).searchMessagesBySubject(subject)[0]!; + const sentMsg = (await GoogleData.withInitializedData(acct)).searchMessagesBySubject(subject)[0]; const message = sentMsg.payload!.body!.data!; /* eslint-enable @typescript-eslint/no-non-null-assertion */ expect(message).to.include('-----BEGIN PGP MESSAGE-----'); @@ -1599,10 +1598,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - multiple compose windows - opening, max 3, order, active', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); // open 3 compose windows await inboxPage.waitAndClick('@action-open-secure-compose-window', { sleepWhenDone: 1 }); await inboxPage.waitAndClick('@action-open-secure-compose-window', { sleepWhenDone: 1 }); @@ -1643,7 +1642,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default.skip( + test.skip( 'oversize attachment does not get erroneously added', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -1663,12 +1662,12 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'rendered reply - can preview attachment', testWithBrowser('ci.tests.gmail', async (t, browser) => { const threadId = '173fd7dbe2fec90c'; const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe'); const replyFrame = await inboxPage.getFrame(['compose.htm']); await replyFrame.waitAndClick('@encrypted-reply'); @@ -1685,12 +1684,12 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'attachments - failed to decrypt', testWithBrowser('compatibility', async (t, browser) => { - const inboxPage = await browser.newPage( + const inboxPage = await browser.newExtensionPage( t, - TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=162ec58d70fe04ef`) + `chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=162ec58d70fe04ef` ); const attachment = await inboxPage.getFrame(['attachment.htm']); await attachment.waitAndClick('@download-attachment'); @@ -1701,7 +1700,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'timeouts when searching WKD - used to never time out', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -1711,11 +1710,11 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default.todo('compose - reply - new gmail threadId fmt'); + test.todo('compose - reply - new gmail threadId fmt'); - ava.default.todo('compose - reply - skip click prompt'); + test.todo('compose - reply - skip click prompt'); - ava.default( + test( 'send signed S/MIME message', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.test.key.imported@gmail.com'; @@ -1739,13 +1738,13 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'send signed and encrypted S/MIME message', testWithBrowser('compatibility', async (t, browser) => { const acctEmail = 'flowcrypt.compatibility@gmail.com'; const passphrase = 'pa$$w0rd'; await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, testConstants.testKeyMultipleSmimeCEA2D53BB9D24871, passphrase, {}, false); - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox(acctEmail)); + const inboxPage = await browser.newExtensionInboxPage(t, acctEmail); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg( composeFrame, @@ -1764,13 +1763,13 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'send signed and encrypted S/MIME message entering a non-primary passphrase', testWithBrowser('compatibility', async (t, browser) => { const acctEmail = 'flowcrypt.compatibility@gmail.com'; const passphrase = 'pa$$w0rd'; await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, testConstants.testKeyMultipleSmimeCEA2D53BB9D24871, passphrase, {}, false); - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox(acctEmail)); + const inboxPage = await browser.newExtensionInboxPage(t, acctEmail); await InboxPageRecipe.finishSessionOnInboxPage(inboxPage); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg( @@ -1794,10 +1793,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'send with single S/MIME cert', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg(composeFrame, { to: 'smime@recipient.com' }, t.title, 'This text should be encrypted into PKCS#7 data', { sign: false, @@ -1814,10 +1813,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'send with several S/MIME certs', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg( composeFrame, @@ -1838,10 +1837,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'send encrypted-only S/MIME message with attachment', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg(composeFrame, { to: 'smime.attachment@recipient.com' }, t.title, 'This text should be encrypted into PKCS#7 data', { sign: false, @@ -1867,14 +1866,14 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'send signed and encrypted S/MIME message with attachment', testWithBrowser('ci.tests.gmail', async (t, browser) => { // todo - this is not yet looking for actual attachment in the result, just checks that it's s/mime message const acctEmail = 'ci.tests.gmail@flowcrypt.test'; const passphrase = 'pa$$w0rd'; await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, testConstants.testKeyMultipleSmimeCEA2D53BB9D24871, passphrase, {}, false); - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox(acctEmail)); + const inboxPage = await browser.newExtensionInboxPage(t, acctEmail); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg(composeFrame, { to: 'smime.attachment@recipient.com' }, t.title); await ComposePageRecipe.pastePublicKeyManually( @@ -1897,10 +1896,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'send with mixed S/MIME and PGP recipients - should show err', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg(composeFrame, { to: 'smime@recipient.com', cc: 'human@flowcrypt.com' }, t.title); await ComposePageRecipe.pastePublicKeyManually(composeFrame, inboxPage, 'smime@recipient.com', testConstants.smimeCert); @@ -1913,11 +1912,11 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'send with OpenPGP recipients as subset of S/MIME recipients', testWithBrowser('ci.tests.gmail', async (t, browser) => { const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox(acctEmail)); + const inboxPage = await browser.newExtensionInboxPage(t, acctEmail); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg( composeFrame, @@ -1945,11 +1944,11 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'send with S/MIME recipients as subset of OpenPGP recipients', testWithBrowser('ci.tests.gmail', async (t, browser) => { const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox(acctEmail)); + const inboxPage = await browser.newExtensionInboxPage(t, acctEmail); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg( composeFrame, @@ -1977,10 +1976,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'send with broken S/MIME cert - err', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg(composeFrame, { to: 'smime@recipient.com' }, t.title); const brokenCert = testConstants.smimeCert.split('\n'); @@ -1990,10 +1989,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'send non-S/MIME cert - err', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg(composeFrame, { to: 'smime@recipient.com' }, t.title); const httpsCert = @@ -2003,10 +2002,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'cannot import expired key in secure compose', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); const to = 'nopgp@recipient.com'; const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg(composeFrame, { to }, t.title); @@ -2023,12 +2022,12 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te // we test that list of public keys get refetched even if we already have a good key // useful when recipient now has a completely different public key - ava.default( + test( 'compose - list of pubkeys gets refetched in compose', testWithBrowser('ci.tests.gmail', async (t, browser) => { const recipientEmail = 'mock.only.pubkey@flowcrypt.com'; // has "somePubkey" on Attester const validKey = protonMailCompatKey; // doesn't really matter which key we import, as long as different from "somePubkey" - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('ci.tests.gmail@flowcrypt.test')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'ci.tests.gmail@flowcrypt.test'); const contactsFrame = await importKeyManuallyAndViewTheNewContact(settingsPage, recipientEmail, validKey, 'IMPORT KEY'); await contactsFrame.waitForContent('@page-contacts', 'openpgp - active - AB8C F86E 3715 7C3F 290D 7200 7ED4 3D79 E961 7655'); await contactsFrame.waitAndClick(`@action-show-pubkey-AB8CF86E37157C3F290D72007ED43D79E9617655-openpgp`, { @@ -2058,11 +2057,11 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te ); // we test that expired key gets re-fetched to become active again - ava.default( + test( 'auto-refresh expired key if newer version of the same key available', testWithBrowser('ci.tests.gmail', async (t, browser) => { // add an expired key manually - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('ci.tests.gmail@flowcrypt.test')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'ci.tests.gmail@flowcrypt.test'); const { recipientEmail, contactsFrame } = await importExpiredKeyForAutoRefresh(settingsPage); // now we want to see that compose page auto-fetches an updated one const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -2086,7 +2085,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te ); // we test that key re-fetching does not happen when attester is disabled - ava.default( + test( "don't auto-refresh expired key if disallowed search on attester", testWithBrowser(undefined, async (t, browser) => { const acct = 'user@no-search-wildcard-domains-client-configuration.flowcrypt.test'; @@ -2103,7 +2102,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'recipient without pub key will turn green & hide password input view when manually updated in different window', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -2127,7 +2126,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'attester client should understand more than one pub key', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -2135,7 +2134,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te await ComposePageRecipe.fillMsg(composePage, { to: recipientEmail }, t.title); await composePage.close(); // Check if multiple keys are imported to multiple.pub.key@flowcrypt.com account - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('ci.tests.gmail@flowcrypt.test')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'ci.tests.gmail@flowcrypt.test'); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const contactsFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-contacts-page', ['contacts.htm', 'placement=settings']); await contactsFrame.waitAll('@page-contacts'); @@ -2157,7 +2156,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'check attester ldap search', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -2171,7 +2170,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }; await ComposePageRecipe.fillMsg(composePage, recipients, t.title); await composePage.close(); - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('ci.tests.gmail@flowcrypt.test')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'ci.tests.gmail@flowcrypt.test'); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const contactsFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-contacts-page', ['contacts.htm', 'placement=settings']); await contactsFrame.waitAll('@page-contacts'); @@ -2188,14 +2187,14 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'check attester ldap timeout', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); const recipients = { to: 'test.ldap.timeout@gmail.com', cc: 'test.flowcrypt.pubkey.timeout@gmail.com' }; await ComposePageRecipe.fillMsg(composePage, recipients, t.title); await composePage.close(); - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('ci.tests.gmail@flowcrypt.test')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'ci.tests.gmail@flowcrypt.test'); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const contactsFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-contacts-page', ['contacts.htm', 'placement=settings']); await contactsFrame.waitAll('@page-contacts'); @@ -2208,7 +2207,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'allows to retry public key search when attester returns error', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compose'); @@ -2219,12 +2218,12 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'do not auto-refresh key if older version of the same key available on attester', testWithBrowser('ci.tests.gmail', async (t, browser) => { const recipientEmail = 'has.older.key.on.attester@recipient.com'; // add a newer expired key manually - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('ci.tests.gmail@flowcrypt.test')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'ci.tests.gmail@flowcrypt.test'); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const contactsFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-contacts-page', ['contacts.htm', 'placement=settings']); await contactsFrame.waitAll('@page-contacts'); @@ -2273,13 +2272,13 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'import S/MIME cert', testWithBrowser('ci.tests.gmail', async (t, browser) => { // the cert since expired, therefore test was updated to reflect that const recipientEmail = 'actalis@meta.33mail.com'; // add S/MIME key manually - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('ci.tests.gmail@flowcrypt.test')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'ci.tests.gmail@flowcrypt.test'); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const contactsFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-contacts-page', ['contacts.htm', 'placement=settings']); await contactsFrame.waitAll('@page-contacts'); @@ -2308,7 +2307,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply - CC&BCC test forward', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=16ce2c965c75e5a6&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=16ce2c965c75e5a6'; @@ -2323,7 +2322,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply - from === acctEmail', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=17d02296bccd4c5c&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=17d02296bccd4c5c'; @@ -2340,7 +2339,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - check reply for web portal messsage', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = @@ -2354,7 +2353,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply - subject starts with Re:', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=17d02296bccd4c5d&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=17d02296bccd4c5d'; @@ -2367,7 +2366,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply - from !== acctEmail', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=17d02268f01c7e40&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=17d02268f01c7e40'; @@ -2380,7 +2379,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply all - from !== acctEmail', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=17d02268f01c7e40&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=17d02268f01c7e40'; @@ -2397,10 +2396,11 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'user@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal', testWithBrowser(undefined, async (t, browser) => { - const acct = 'user@standardsubdomainfes.localhost:8001'; // added port to trick extension into calling the mock + const port = t.urls?.port; + const acct = `user@standardsubdomainfes.localhost:${port}`; // added port to trick extension into calling the mock const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, acct); await SetupPageRecipe.manualEnter( settingsPage, @@ -2409,7 +2409,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te { isSavePassphraseChecked: false, isSavePassphraseHidden: false } ); // add names to contacts - const dbPage = await browser.newPage(t, TestUrls.extension('chrome/dev/ci_unit_test.htm')); + const dbPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); await dbPage.page.evaluate(async () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const db = await (window as any).ContactStore.dbOpen(); @@ -2420,7 +2420,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }); await dbPage.close(); const subject = 'PWD encrypted message with FES - ID TOKEN'; - const composePage = await ComposePageRecipe.openStandalone(t, browser, 'user@standardsubdomainfes.localhost:8001'); + const composePage = await ComposePageRecipe.openStandalone(t, browser, `user@standardsubdomainfes.localhost:${port}`); await ComposePageRecipe.fillMsg(composePage, { to: 'to@example.com', bcc: 'bcc@example.com' }, subject); const fileInput = (await composePage.target.$('input[type=file]')) as ElementHandle; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion @@ -2444,10 +2444,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'user2@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES - Reply rendering', testWithBrowser(undefined, async (t, browser) => { - const acct = 'user2@standardsubdomainfes.localhost:8001'; // added port to trick extension into calling the mock + const acct = `user2@standardsubdomainfes.localhost:${t.urls?.port}`; // added port to trick extension into calling the mock const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, acct); await SetupPageRecipe.manualEnter( settingsPage, @@ -2456,7 +2456,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te { isSavePassphraseChecked: false, isSavePassphraseHidden: false } ); const appendUrl = 'threadId=1803be2e506153d2&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=1803be3182d1937b'; - const composePage = await ComposePageRecipe.openStandalone(t, browser, 'user2@standardsubdomainfes.localhost:8001', { + const composePage = await ComposePageRecipe.openStandalone(t, browser, acct, { appendUrl, hasReplyPrompt: true, }); @@ -2504,7 +2504,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'compose - reply box correctly resizes recipients on opening', testWithBrowser('ci.tests.gmail', async (t, browser) => { const acct = 'ci.tests.gmail@flowcrypt.test'; @@ -2521,10 +2521,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'user3@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal - pubkey recipient in bcc', testWithBrowser(undefined, async (t, browser) => { - const acct = 'user3@standardsubdomainfes.localhost:8001'; // added port to trick extension into calling the mock + const acct = `user3@standardsubdomainfes.localhost:${t.urls?.port}`; // added port to trick extension into calling the mock const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, acct); await SetupPageRecipe.manualEnter( settingsPage, @@ -2533,7 +2533,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te { isSavePassphraseChecked: false, isSavePassphraseHidden: false } ); const subject = 'PWD encrypted message with FES - pubkey recipient in bcc'; - const composePage = await ComposePageRecipe.openStandalone(t, browser, 'user3@standardsubdomainfes.localhost:8001'); + const composePage = await ComposePageRecipe.openStandalone(t, browser, acct); await ComposePageRecipe.fillMsg(composePage, { to: 'to@example.com', bcc: 'flowcrypt.compatibility@gmail.com' }, subject); await composePage.waitAndType('@input-password', 'gO0d-pwd'); await composePage.waitAndClick('@action-send', { delay: 1 }); @@ -2545,10 +2545,10 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'user4@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal - a send fails with gateway update error', testWithBrowser(undefined, async (t, browser) => { - const acct = 'user4@standardsubdomainfes.localhost:8001'; // added port to trick extension into calling the mock + const acct = `user4@standardsubdomainfes.localhost:${t.urls?.port}`; // added port to trick extension into calling the mock const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, acct); await SetupPageRecipe.manualEnter( settingsPage, @@ -2558,7 +2558,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te ); const subject = 'PWD encrypted message with FES web portal - a send fails with gateway update error - ' + testVariant; const expectedNumberOfPassedMessages = (await GoogleData.withInitializedData(acct)).searchMessagesBySubject(subject).length; - const composePage = await ComposePageRecipe.openStandalone(t, browser, 'user4@standardsubdomainfes.localhost:8001'); + const composePage = await ComposePageRecipe.openStandalone(t, browser, acct); await ComposePageRecipe.fillMsg(composePage, { to: 'gatewayfailure@example.com' }, subject); await composePage.waitAndType('@input-password', 'gO0d-pwd'); await composePage.waitAndClick('@action-send', { delay: 1 }); @@ -2570,7 +2570,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'first.key.revoked@key-manager-autoimport-no-prv-create.flowcrypt.test - selects valid own key when saving draft or sending', testWithBrowser(undefined, async (t, browser) => { const acct = 'first.key.revoked@key-manager-autoimport-no-prv-create.flowcrypt.test'; @@ -2583,7 +2583,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'revoked@key-manager-autoimport-no-prv-create.flowcrypt.test - shows modal not submitting to attester', testWithBrowser(undefined, async (t, browser) => { const acct = 'revoked@key-manager-autoimport-no-prv-create.flowcrypt.test'; @@ -2594,7 +2594,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'revoked@key-manager-autoimport-no-prv-create-no-attester-submit.flowcrypt.test - cannot draft or send msg', testWithBrowser(undefined, async (t, browser) => { const acct = 'revoked@key-manager-autoimport-no-prv-create-no-attester-submit.flowcrypt.test'; @@ -2633,8 +2633,7 @@ const sendImgAndVerifyPresentInSentMsg = async (t: AvaContext, browser: BrowserH }, imgBase64); await ComposePageRecipe.sendAndClose(composePage); // get sent msg id from mock - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const sentMsg = (await GoogleData.withInitializedData('flowcrypt.compatibility@gmail.com')).searchMessagesBySubject(subject)[0]!; + const sentMsg = (await GoogleData.withInitializedData('flowcrypt.compatibility@gmail.com')).searchMessagesBySubject(subject)[0]; if (sendingType === 'plain') { expect(sentMsg.payload?.body?.data).to.match(/Test Sending Plain Message With Image/); return; @@ -2672,7 +2671,7 @@ const sendTextAndVerifyPresentInSentMsg = async ( await ComposePageRecipe.sendAndClose(composePage); /* eslint-disable @typescript-eslint/no-non-null-assertion */ // get sent msg from mock - const sentMsg = (await GoogleData.withInitializedData('flowcrypt.compatibility@gmail.com')).searchMessagesBySubject(subject)[0]!; + const sentMsg = (await GoogleData.withInitializedData('flowcrypt.compatibility@gmail.com')).searchMessagesBySubject(subject)[0]; const message = encodeURIComponent(sentMsg.payload!.body!.data!); /* eslint-enable @typescript-eslint/no-non-null-assertion */ await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -2685,13 +2684,10 @@ const sendTextAndVerifyPresentInSentMsg = async ( }; const setRequirePassPhraseAndOpenRepliedMessage = async (t: AvaContext, browser: BrowserHandle, passphrase: string) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings()); + const settingsPage = await browser.newExtensionSettingsPage(t); await SettingsPageRecipe.forgetAllPassPhrasesInStorage(settingsPage, passphrase); // Open Message Page - const inboxPage = await browser.newPage( - t, - TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=16b584ed95837510`) - ); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=16b584ed95837510`); await inboxPage.waitAll('iframe'); // Get Reply Window (Composer) and click on reply button. const replyFrame = await inboxPage.getFrame(['compose.htm']); diff --git a/test/source/tests/decrypt.ts b/test/source/tests/decrypt.ts index 9613615d2fc..f813c2c45ba 100644 --- a/test/source/tests/decrypt.ts +++ b/test/source/tests/decrypt.ts @@ -1,6 +1,6 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ -import * as ava from 'ava'; +import test from 'ava'; import { Config, TestVariant, Util } from './../util'; import { testConstants } from './tooling/consts'; @@ -8,7 +8,6 @@ import { BrowserRecipe } from './tooling/browser-recipe'; import { GoogleData } from './../mock/google/google-data'; import { InboxPageRecipe } from './page-recipe/inbox-page-recipe'; import { SettingsPageRecipe } from './page-recipe/settings-page-recipe'; -import { TestUrls } from './../browser/test-urls'; import { TestWithBrowser } from './../test'; import { expect } from 'chai'; import { PageRecipe } from './page-recipe/abstract-page-recipe'; @@ -16,12 +15,12 @@ import { Buf } from '../core/buf'; export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: TestWithBrowser) => { if (testVariant !== 'CONSUMER-LIVE-GMAIL') { - ava.default( + test( `decrypt - detect bogus pgp message`, testWithBrowser('compatibility', async (t, browser) => { const threadId = '17d7a32a0613071d'; const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitForSelTestState('ready'); await inboxPage.waitAll('iframe'); const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); @@ -32,12 +31,12 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - show warning for remote images`, testWithBrowser('compatibility', async (t, browser) => { const threadId = '1850b93d7772173c'; const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitForSelTestState('ready'); await inboxPage.waitAll('iframe'); const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); @@ -46,12 +45,12 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - show inline image when user clicks show image`, testWithBrowser('compatibility', async (t, browser) => { const threadId = '1850f9608240f758'; const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitForSelTestState('ready'); await inboxPage.waitAll('iframe'); const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); @@ -61,12 +60,12 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - outlook message with ATTxxxx encrypted email doesn't show empty attachment`, testWithBrowser('compatibility', async (t, browser) => { const threadId = '17dbdf2425ac0f29'; const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitForSelTestState('ready'); await inboxPage.waitAll('iframe'); expect(await inboxPage.isElementPresent('@container-attachments')).to.equal(false); @@ -74,7 +73,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'decrypt - encrypted text inside "message" attachment is correctly decrypted', testWithBrowser('ci.tests.gmail', async (t, browser) => { const acctEmail = 'ci.tests.gmail@flowcrypt.test'; @@ -90,12 +89,12 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - render plain text for "message" attachment (which has plain text)`, testWithBrowser('ci.tests.gmail', async (t, browser) => { const threadId = '184a87a7b32dd009'; const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitForSelTestState('ready'); await inboxPage.waitAll('iframe'); expect(await inboxPage.isElementPresent('@container-attachments')).to.equal(true); @@ -107,7 +106,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - outlook message with ATTxxxx encrypted email is correctly decrypted`, testWithBrowser('compatibility', async (t, browser) => { const acctEmail = 'flowcrypt.compatibility@gmail.com'; @@ -119,7 +118,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - without a subject`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -133,7 +132,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [enigmail] encrypted iso-2022-jp pgp/mime`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -146,7 +145,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [enigmail] encrypted iso-2022-jp, plain text`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -159,7 +158,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - iso-2022-jp, signed plain text`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -172,7 +171,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - quoted part parsing will not crash browser`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -186,7 +185,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [flowcrypt] signed message inline`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -199,7 +198,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [gpgmail] signed message will get parsed and rendered (though verification fails, enigmail does the same)`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -212,7 +211,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [gpg] signed fully armored message`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -226,7 +225,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [flowcrypt] encrypted hello`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -239,7 +238,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [flowcrypt] encrypted utf8`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -252,7 +251,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [flowcrypt] encrypted thai utf8`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -265,7 +264,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [facebook] encrypted utf8`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -278,7 +277,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [gpgmail] encrypted utf8`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -291,7 +290,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [enigmail] encrypted utf8`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -305,7 +304,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [enigmail] encrypted pgp/mime`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -318,7 +317,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [enigmail] encrypted inline`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -331,7 +330,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [enigmail] encrypted+signed inline`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -344,7 +343,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [enigmail] encrypted+signed pgp/mime`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -357,7 +356,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [enigmail] encrypted+signed+file pgp/mime + load from gmail`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -370,7 +369,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - encrypted missing checksum`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -383,7 +382,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - pgp/mime with large attachment - mismatch`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -396,7 +395,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - pgp/mime with large attachment`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -410,7 +409,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - pgp/mime with large attachment as message.asc`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -424,7 +423,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - pgp/mime with small attachments as message.asc`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -437,7 +436,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [flowcrypt] escape and keep tags in plain text`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -450,7 +449,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [symantec] base64 german umlauts`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -463,7 +462,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [gnupg v2] thai text`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -476,7 +475,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [gnupg v2] thai text in html`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -489,7 +488,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [enigmail] basic html`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -502,7 +501,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [thunderbird] unicode chinese`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -516,7 +515,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [security] mdc - missing - error`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -528,7 +527,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [security] mdc - modification detected - error`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -540,7 +539,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( `decrypt - [security] signed message - maliciously modified - should not pass`, testWithBrowser('compatibility', async (t, browser) => { const acctEmail = 'flowcrypt.compatibility@gmail.com'; @@ -619,7 +618,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( `decrypt - [everdesk] message encrypted for sub but claims encryptedFor:primary,sub`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -632,7 +631,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( `decrypt - [pep] pgp/mime message with text encoded as inline attachment`, testWithBrowser('compatibility', async (t, browser) => { await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { @@ -646,14 +645,14 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - by entering pass phrase + remember in session', testWithBrowser('compatibility', async (t, browser) => { const pp = Config.key('flowcrypt.compatibility.1pp1').passphrase; const threadId = '15f7f5630573be2d'; const expectedContent = 'The International DUBLIN Literary Award is an international literary award'; const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings()); + const settingsPage = await browser.newExtensionSettingsPage(t); await SettingsPageRecipe.forgetAllPassPhrasesInStorage(settingsPage, pp); // requires pp entry await InboxPageRecipe.checkDecryptMsg(t, browser, { @@ -673,12 +672,12 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( "decrypt - thunderbird - signedHtml verifyDetached doesn't duplicate PGP key section", testWithBrowser('compatibility', async (t, browser) => { const threadId = '17daefa0eb077da6'; const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe'); const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); await pgpBlock.waitForSelTestState('ready'); @@ -687,12 +686,12 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - print feature in pgp block', testWithBrowser('compatibility', async (t, browser) => { const threadId = '182917712be838e1'; const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe'); const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); await pgpBlock.waitForSelTestState('ready'); @@ -706,12 +705,12 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( "decrypt - thunderbird - signedMsg verifyDetached doesn't duplicate PGP key section", testWithBrowser('compatibility', async (t, browser) => { const threadId = '17dad75e63e47f97'; const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe'); const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); await pgpBlock.waitForSelTestState('ready'); @@ -720,12 +719,12 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - thunderbird - signing key is rendered in signed and encrypted message', testWithBrowser('ci.tests.gmail', async (t, browser) => { const threadId = '175adb163ac0d69b'; const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe'); const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); await pgpBlock.waitForSelTestState('ready'); @@ -734,12 +733,12 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - thunderbird - signed text is recognized', testWithBrowser('compatibility', async (t, browser) => { const threadId = '17dad75e63e47f97'; const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe', { timeout: 2 }); const urls = await inboxPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 10, appearIn: 20 }); expect(urls.length).to.equal(1); @@ -753,7 +752,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'verification - message text is rendered prior to pubkey fetching', testWithBrowser('compatibility', async (t, browser) => { const msgId = '17dad75e63e47f97'; @@ -768,7 +767,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'verification - public key fetched from WKD', testWithBrowser('compatibility', async (t, browser) => { const senderEmail = 'only.on.wkd@signing.test'; @@ -784,7 +783,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - fetched pubkey is automatically saved to contacts', testWithBrowser('compatibility', async (t, browser) => { const msgId = '17dad75e63e47f97'; @@ -793,7 +792,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== const acctAttr = acctEmail.replace(/[\.@]/g, ''); const senderAttr = senderEmail.replace(/[\.@]/g, ''); { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acctEmail)); + const settingsPage = await browser.newExtensionSettingsPage(t, acctEmail); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const contactsFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-contacts-page', ['contacts.htm', 'placement=settings']); await contactsFrame.waitAll('@page-contacts'); @@ -809,7 +808,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== signature: 'signed', }); { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acctEmail)); + const settingsPage = await browser.newExtensionSettingsPage(t, acctEmail); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const contactsFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-contacts-page', ['contacts.htm', 'placement=settings']); await contactsFrame.waitAll('@page-contacts'); @@ -823,12 +822,12 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - unsigned encrypted message', testWithBrowser('compatibility', async (t, browser) => { const threadId = '17918a9d7ca2fbac'; const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe'); const urls = await inboxPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 3 }); expect(urls.length).to.equal(1); @@ -842,12 +841,12 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'signature - sender is different from pubkey uid', testWithBrowser('ci.tests.gmail', async (t, browser) => { const threadId = '1766644f13510f58'; const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe', { timeout: 2 }); const urls = await inboxPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 10, appearIn: 20 }); expect(urls.length).to.equal(1); @@ -861,7 +860,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'signature - verification succeeds when signed with a second-best key', testWithBrowser('ci.tests.gmail', async (t, browser) => { const threadId = '1766644f13510f58'; @@ -873,7 +872,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== '-----BEGIN PGP PUBLIC KEY BLOCK-----\r\nVersion: FlowCrypt Email Encryption [BUILD_REPLACEABLE_VERSION]\r\nComment: Seamlessly send and receive encrypted email\r\n\r\nxjMEYZeW2RYJKwYBBAHaRw8BAQdAT5QfLVP3y1yukk3MM/oiuXLNe1f9az5M\r\nBnOlKdF0nKnNJVNvbWVib2R5IDxTYW1zNTBzYW1zNTBzZXB0QEdtYWlsLkNv\r\nbT7CjwQQFgoAIAUCYZeW2QYLCQcIAwIEFQgKAgQWAgEAAhkBAhsDAh4BACEJ\r\nEMrSTYqLk6SUFiEEBP90ux3d6kDwDdzvytJNiouTpJS27QEA7pFlkLfD0KFQ\r\nsH/dwb/NPzn5zCi2L9gjPAC3d8gv1fwA/0FjAy/vKct4D7QH8KwtEGQns5+D\r\nP1WxDr4YI2hp5TkAzjgEYZeW2RIKKwYBBAGXVQEFAQEHQKNLY/bXrhJMWA2+\r\nWTjk3I7KhawyZfLomJ4hovqr7UtOAwEIB8J4BBgWCAAJBQJhl5bZAhsMACEJ\r\nEMrSTYqLk6SUFiEEBP90ux3d6kDwDdzvytJNiouTpJQnpgD/c1CzfS3YzJUx\r\nnFMrhjiE0WVgqOV/3CkfI4m4RA30QUIA/ju8r4AD2h6lu3Mx/6I6PzIRZQty\r\nLvTkcu4UKodZa4kK\r\n=7C4A\r\n-----END PGP PUBLIC KEY BLOCK-----\r\n', 'sender@example.com' ); - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe', { timeout: 2 }); const urls = await inboxPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 10, appearIn: 20 }); expect(urls.length).to.equal(1); @@ -887,7 +886,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( `decrypt - missing pubkey in "incorrect message digest" scenario`, testWithBrowser('ci.tests.gmail', async (t, browser) => { const msgId = '1766644f13510f58'; @@ -913,7 +912,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - re-fetch signed-only message from API on non-fatal verification error', testWithBrowser('compatibility', async (t, browser) => { const msgId = '17daefa0eb077da6'; @@ -939,7 +938,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - protonmail - load pubkey into contact + verify detached msg', testWithBrowser('compatibility', async (t, browser) => { const textParams = @@ -970,7 +969,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - protonmail - auto TOFU load matching pubkey first time', testWithBrowser('compatibility', async (t, browser) => { const params = @@ -985,7 +984,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - verify encrypted+signed message', testWithBrowser('compatibility', async (t, browser) => { const params = `?frameId=none&message=&msgId=1617429dc55600db&senderEmail=martin%40politick.ca&isOutgoing=___cu_false___&acctEmail=flowcrypt.compatibility%40gmail.com`; @@ -998,7 +997,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - load key - expired key', testWithBrowser('compatibility', async (t, browser) => { const pubFrameUrl = `chrome/elements/pgp_pubkey.htm?frameId=none&armoredPubkey=${encodeURIComponent( @@ -1013,7 +1012,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - load key - unusable key', testWithBrowser('compatibility', async (t, browser) => { const pubFrameUrl = `chrome/elements/pgp_pubkey.htm?frameId=none&armoredPubkey=${encodeURIComponent( @@ -1027,7 +1026,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - wrong message - checksum throws error', testWithBrowser('compatibility', async (t, browser) => { const threadId = '15f7ffb9320bd79e'; @@ -1043,7 +1042,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - inbox - encrypted message inside signed', testWithBrowser('compatibility', async (t, browser) => { const inboxPage = await browser.newPage(t, 'chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility%40gmail.com&threadId=16f0bfce331ca2fd'); @@ -1057,7 +1056,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - inbox - check for rel="noopener noreferrer" attribute in PGP/MIME links', testWithBrowser('compatibility', async (t, browser) => { const inboxPage = await browser.newPage(t, 'chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility%40gmail.com&threadId=1762c9a49bedbf6f'); @@ -1069,7 +1068,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - inbox - Verify null window.opener object after opening PGP/MIME links', testWithBrowser('compatibility', async (t, browser) => { const inboxPage = await browser.newPage(t, 'chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility%40gmail.com&threadId=1762c9a49bedbf6f'); @@ -1085,9 +1084,9 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default.todo('decrypt - by entering secondary pass phrase'); + test.todo('decrypt - by entering secondary pass phrase'); - ava.default( + test( `decrypt - don't allow api path traversal`, testWithBrowser('compatibility', async (t, browser) => { const params = @@ -1099,7 +1098,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( `decrypt - signed only - parse error in a badge`, testWithBrowser('compatibility', async (t, browser) => { const params = '?frame_id=&msgId=corrupted-1&signature=___cu_true___&senderEmail=&account_email=flowcrypt.compatibility%40gmail.com'; @@ -1113,12 +1112,12 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( 'decrypt - prevent rendering of attachments from domain sources other than flowcrypt.s3.amazonaws.com1', testWithBrowser('compatibility', async (t, browser) => { const threadId1 = '184cc6aa8e884397'; const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId1}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId1}`); await inboxPage.waitAll('iframe'); const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); await pgpBlock.waitForSelTestState('ready'); @@ -1127,7 +1126,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( `decrypt - try path traversal forward slash workaround`, testWithBrowser('compatibility', async (t, browser) => { const params = @@ -1139,7 +1138,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - ava.default( + test( `verify - sha1 shows error`, testWithBrowser('compatibility', async (t, browser) => { const msg = `-----BEGIN PGP MESSAGE----- @@ -1165,7 +1164,7 @@ d6Z36//MsmczN00Wd60t9T+qyLz0T4/UG2Y9lgf367f3d+kYPE0LS7mXuFmjlPXfw0nKyVsSeFiu }) ); - ava.default( + test( 'verify - Kraken - urldecode signature', testWithBrowser('compatibility', async (t, browser) => { const params = `?frameId=frame_ZRxshLEFdc&message=&msgId=171d138c8750863b&senderEmail=Kraken%20%3Ccensored%40email.com%3E&isOutgoing=___cu_false___&signature=___cu_true___&acctEmail=flowcrypt.compatibility%40gmail.com&parentTabId=12%3A0`; diff --git a/test/source/tests/elements.ts b/test/source/tests/elements.ts index 7a64651475b..a5e5335000b 100644 --- a/test/source/tests/elements.ts +++ b/test/source/tests/elements.ts @@ -1,6 +1,6 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ -import * as ava from 'ava'; +import test from 'ava'; import { TestVariant } from '../util'; import { TestWithBrowser } from '../test'; @@ -9,7 +9,7 @@ import { SettingsPageRecipe } from './page-recipe/settings-page-recipe'; export const defineElementTests = (testVariant: TestVariant, testWithBrowser: TestWithBrowser) => { if (testVariant !== 'CONSUMER-LIVE-GMAIL') { - ava.default( + test( 'elements/pgp_pubkey.htm renders a public key', testWithBrowser('compatibility', async (t, browser) => { const pub = `-----BEGIN%20PGP%20PUBLIC%20KEY%20BLOCK-----%0AVersion%3A%20CryptUp%204.3.6%20Gmail%20Encryption%20https%3A%2F%2Fcryptup.org%0AComment%3A%20Seamlessly%20send%2C%20receive%20and%20search%20encrypted%20email%0A%0AxsFNBFj%2FaG8BEADO625P5MArNIVlMBPp%2FHM1lYD1gcVwgYl4aHuXohDMS6dv%0AVAlSDXMVWwbsXJ9T3AxYIL3ZoOFDc1Jy0AqBKhYoOYm5miYHpOQtP%2FM4V6fK%0A3rhmc8C1LP1JXuaEXS0w7MQig8JZC08ECUH1%2FGnhm3tyacRgrAr13s591Obj%0AoP%2FkwglOUjKDYvkXXk9iwouU85sh9HKwC4wR6idFhFSnsl8xp4FI4plLQPTy%0AEa1nf3l%2BoVqCFT5moVtsew7qUD5mWkgytEdr728Sqh5vjiO%2Blc6cjqb0PK77%0ADAuhTel1bV5PRCtRom%2FqrqmOz4MbE5wd2kU%2FJxFPIXZ1BKyicT%2FQ6I9MXjni%0A77Bl91x0V9brnBqyhfY524Vlm%2F2AEb3H9I10rsTBtU4TT%2BSJOlwyU1V7hDkJ%0AKq1zTrVjCvoPcTBXGx9xSZmJO4TI7frNZFiJ5uiYwTYPwp3Yze69y%2FNORwme%0AZlXtXJbzpVvRzXUzex89c6pFiKE8mC5%2FDV%2FeJanBYKgSyGEiHq9U6kDJrTN4%0A%2FfSjiIJ0fWK3bcYwyYUbf9%2B%2FJcLSo2sG259FuRF75yxIe2u2RLSh62plEsyb%0AcpD545pvlrKIvwg%2F1hio999lMnSjj%2BhfNQ7A%2BXm5BWiSzrJ1fR1Oo5rq68kY%0A1C4K8FUQwP3zEF2YDoqbBEnYaxaH7HUcbc34xQARAQABzSlDcnlwdFVwIFRl%0Ac3RlciA8Y3J5cHR1cC50ZXN0ZXJAZ21haWwuY29tPsLBdQQQAQgAKQUCWP9o%0AcAYLCQcIAwIJEAbKVT7CRV1wBBUIAgoDFgIBAhkBAhsDAh4BAAAvwQ%2F%2BIaTX%0Am4ZrqA1h2N%2BgYSUiNkLKnVVZNTdVKSRCEvHNZaYHqZDK5mO9TRKlbz04bIle%0AhfYzt0MW65AmZm5vtp16TTzXQVpFv1YGbFFkol7qR2chzXdnbOCz172W0cKr%0AWu8exVr4XR1C7R6UVckltfouq%2FJGe4pDFwYshluL8ZezCCWDeno6y5JJJr98%0AobKWtSMw0%2B0XqMqFsTP3%2FkF77cWfeZ6aE7Tugq2vRIVg1CuaDZKnrGYPBWbw%0AYZA7r0MTLEHMNm3NWGcmA6BZyAqWLe7ocG%2B%2BDWlXC2AsScUqg26D2pmh4089%0A2%2Fi54ecThwzVmtaycWou6x7E7hEqDGGdD5RorVJ5FqEMq4NsBit43loV7Hoo%0A1R4IW6bVANIqFGUv0VS0MA8%2B7ce1UN9taC762f9idRfNBY0yi9u5hoinSrJo%0ALl%2F489nhyqL74HyelSghK2QusavHCe9BVsHR%2BH0kwszDMtXjDBJtkKRI9FcK%0A%2FQfvU4OvvVKNNSbkz1zaXrGI2YOu4p3CHK%2BaQCluR3PhldVUSDR7wT%2FasfWx%0AMH43juH%2BC0kXonRqye7cDs%2B3wi4qfrJw%2FGYtwC0Jfza%2FOlyuyE%2B1AlVpEBKV%0A7gG%2B6iKTIl2G5DnBN%2FtdfckLNSsYDVby7%2BaZV3CtVvuhfeAjN9YluNqZZBSD%0AqOym88BUsEFLOdzBLbbOwU0EWP9obwEQAKKVKmNQsbpNlhuFZydHjqf%2BAaBB%0AQsJb9Q7zLSuUABmBLUG9%2BohSdb1tsI5MEq7Ldksy2sF4KsY6KBHg0VK4Ndu8%0AKSzeVFlgESyizryt%2Fa8Jad%2FdaujYdJ5fliVx46XYAuVXROhes0Plpa8aQGwU%0AumbV%2Fs2INXqo8HwDke0UI42%2Bk%2FOG2SkkiLGTU2US3OMk85bWoqHi9fYkmM7Y%0ATJRt6dJgwjqevfIvEFUjh3i6ipFSwp%2BB1uS3%2FTHtc%2Fi066wWZwIWb0Z1nsAh%0AVpikL6ckaLiEhkvUEkL%2FmqTfIv0wJAsAsRvXKZvmO8qQrKq8UQrADjfMSP%2F4%0AscohiuwjPRYqpt3NyqrliCcTRWZTBLXj7w1E2m4ZcAeRUFFv1LhcLPkR3uBo%0AmxaoKqbwT6D64sz%2BaXopIMopcsWFf64zFnYBAJN7tYOmIQQMH5aZGNV%2B8v6u%0AWvPpgEzAFQutDUVr2ttAIfyK%2BHPu57pHOAB51N%2Bl04en9WXeUmT1cqpqaXAK%0AV9cEH3oRkpBRz5waIW1LmElWbubjEWKZfLB8NgvGMsA0lMqsaaVdV0swoehQ%0AHuvXIQv1eeBLK%2FsAL3%2FVCStMwkW8gfaL8%2BbEKDK%2Bl4Jd1mhXa%2BVAyzTAEsTT%0AyAaYP3Y1fR595LA8YHBsfu4ugYzqc7%2F71ExvE%2B7S8kdBv0wOiekWs7zVABEB%0AAAHCwV8EGAEIABMFAlj%2FaHMJEAbKVT7CRV1wAhsMAADFiw%2F%2Fe8AN74gI2LD%2B%0A827r3742%2FasQ76JnqM63GDT3c9Tp6N5i7HMxBw%2BKdcPuEgQHWADdpDBcPtRG%0AkQUD9ty2mtvGsYSg27G%2FHPyb2OYSLf6LF7MQPbHl0REvIjyGKvM0jV6sfGQA%0A1DkfY5EdbQIaqamB73GZrG1vmwXYR4NBFYHtqhDxcvOJNDTlTNRcI957G5cp%0AvWS68d2FkCHHlSRsZdLt1JknTaUdCYArgkJSLRMSWPAwWDFZpPJJHf7lkEgU%0A1quql3%2F7wEShDKqfmgOYDzBZ4K0Hy%2F8jSHpiEWlgF6F8Kl0HCRs%2BARhoAbl%2F%0AM45Xb0%2BbDp30xKJMoHkoOyveWZWz2MHb00ISzDlKEBe2MrCPJe6iHVFtqjPM%0A3qZ93hyIaYKu0H8Hc3HlqYB5muvN80FFX7FNPXc4NiIoRp5Nd6F2qvMMnuD%2B%0AAsOKCgQ4KcTa8Joe4%2BcJ8ba3rizK45ktPvvJNzSeB6Zj9rSIiF9iU4a49QDU%0Am9mzGSLx%2FpFtJ4kfFqiVs6htbtobOBKFjUVrhJtKsFuk7awoTA6cl9ytd%2BSA%0A%2BUxSdqb6cFHq5YjR%2BCwRAG0HF2bdd6XvYtZnjwzTkMwYQzG30QPFTpy%2Fnu%2By%0AOwlAeRiv2EMNWKHjnNVWpqwApGGHzFV%2Bg12fK%2BDgurILj%2F8qM1pZBvu3Q8bI%0ACkFQRDXhui8%3D%0A%3Dy3QV%0A-----END%20PGP%20PUBLIC%20KEY%20BLOCK-----`; @@ -20,7 +20,7 @@ export const defineElementTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default( + test( 'elements/passphrase.htm shows a toast when unlocking some other key', testWithBrowser('compatibility', async (t, browser) => { const acctEmail = 'flowcrypt.compatibility@gmail.com'; @@ -41,10 +41,10 @@ export const defineElementTests = (testVariant: TestVariant, testWithBrowser: Te }) ); - ava.default.todo('elements/pgp_pubkey shows graceful error when pubkey not usable'); + test.todo('elements/pgp_pubkey shows graceful error when pubkey not usable'); - ava.default.todo('elements/pgp_pubkey can render several pubkeys in one armor'); + test.todo('elements/pgp_pubkey can render several pubkeys in one armor'); - ava.default.todo('compose - elements/pgp_pubkey can import several pubkeys in one armor'); + test.todo('compose - elements/pgp_pubkey can import several pubkeys in one armor'); } }; diff --git a/test/source/tests/flaky.ts b/test/source/tests/flaky.ts index a2795b3a80d..8c6093eb232 100644 --- a/test/source/tests/flaky.ts +++ b/test/source/tests/flaky.ts @@ -1,6 +1,6 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ -import * as ava from 'ava'; +import test from 'ava'; import { expect } from 'chai'; import { Config, TestVariant, Util } from './../util'; @@ -12,7 +12,6 @@ import { SettingsPageRecipe } from './page-recipe/settings-page-recipe'; import { TestWithBrowser } from './../test'; import { Stream } from '../core/stream'; import { InboxPageRecipe } from './page-recipe/inbox-page-recipe'; -import { TestUrls } from '../browser/test-urls'; import { OauthPageRecipe } from './page-recipe/oauth-page-recipe'; import { testConstants } from './tooling/consts'; import { SetupPageRecipe } from './page-recipe/setup-page-recipe'; @@ -26,7 +25,7 @@ import { GoogleData } from '../mock/google/google-data'; export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: TestWithBrowser) => { if (testVariant !== 'CONSUMER-LIVE-GMAIL') { - ava.default( + test( 'compose - own key expired - update and retry', testWithBrowser(undefined, async (t, browser) => { const expiredKey = @@ -78,7 +77,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'setup - create key - with backup to inbox', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.new.manual@gmail.com'); @@ -92,7 +91,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'setup - create key - choose no backup', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.new.manual@gmail.com'); @@ -106,7 +105,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'setup - create key - backup as file - submit pubkey', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.new.manual@gmail.com'); @@ -120,7 +119,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'create@prv-create-no-prv-backup.flowcrypt.test - create key allowed but backups not', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'setup@prv-create-no-prv-backup.flowcrypt.test'); @@ -134,7 +133,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'compose - reply all - from === acctEmail', testWithBrowser('compatibility', async (t, browser) => { const appendUrl = 'threadId=17d02296bccd4c5c&skipClickPrompt=___cu_false___&ignoreDraft=___cu_false___&replyMsgId=17d02296bccd4c5c'; @@ -157,7 +156,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'user@no-submit-client-configuration.flowcrypt.test - do not submit to attester on key generation', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'user@no-submit-client-configuration.flowcrypt.test'); @@ -173,7 +172,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'settings - generate rsa3072 key', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'user@no-submit-client-configuration.flowcrypt.test'; @@ -201,10 +200,11 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'user4@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal - some sends fail with BadRequest error', testWithBrowser(undefined, async (t, browser) => { - const acct = 'user4@standardsubdomainfes.localhost:8001'; // added port to trick extension into calling the mock + const port = t.urls?.port; + const acct = `user4@standardsubdomainfes.localhost:${port}`; // added port to trick extension into calling the mock const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, acct); await SetupPageRecipe.manualEnter( settingsPage, @@ -213,7 +213,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test { isSavePassphraseChecked: false, isSavePassphraseHidden: false } ); // add a name to one of the contacts - const dbPage = await browser.newPage(t, TestUrls.extension('chrome/dev/ci_unit_test.htm')); + const dbPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); await dbPage.page.evaluate(async () => { /* eslint-disable @typescript-eslint/no-explicit-any */ const db = await (window as any).ContactStore.dbOpen(); @@ -224,7 +224,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test const subject = 'PWD encrypted message with FES web portal - some sends fail with BadRequest error - ' + testVariant; let expectedNumberOfPassedMessages = (await GoogleData.withInitializedData(acct)).searchMessagesBySubject(subject).length; // 1. vague Gmail error with partial success - let composePage = await ComposePageRecipe.openStandalone(t, browser, 'user4@standardsubdomainfes.localhost:8001'); + let composePage = await ComposePageRecipe.openStandalone(t, browser, `user4@standardsubdomainfes.localhost:${port}`); await ComposePageRecipe.fillMsg(composePage, { to: 'to@example.com', cc: 'cc@example.com', bcc: 'flowcrypt.compatibility@gmail.com' }, subject); await composePage.waitAndType('@input-password', 'gO0d-pwd'); await composePage.waitAndClick('@action-send', { delay: 1 }); @@ -237,7 +237,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test await composePage.close(); expect((await GoogleData.withInitializedData(acct)).searchMessagesBySubject(subject).length).to.equal(++expectedNumberOfPassedMessages); // 2. vague Gmail error with all failures - composePage = await ComposePageRecipe.openStandalone(t, browser, 'user4@standardsubdomainfes.localhost:8001'); + composePage = await ComposePageRecipe.openStandalone(t, browser, `user4@standardsubdomainfes.localhost:${port}`); await ComposePageRecipe.fillMsg(composePage, { cc: 'cc@example.com', bcc: 'flowcrypt.compatibility@gmail.com' }, subject); await composePage.waitAndType('@input-password', 'gO0d-pwd'); await composePage.waitAndClick('@action-send', { delay: 1 }); @@ -249,7 +249,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test await composePage.close(); expect((await GoogleData.withInitializedData(acct)).searchMessagesBySubject(subject).length).to.equal(expectedNumberOfPassedMessages); // + 0 messages // 3. "invalid To" Gmail error with partial success - composePage = await ComposePageRecipe.openStandalone(t, browser, 'user4@standardsubdomainfes.localhost:8001'); + composePage = await ComposePageRecipe.openStandalone(t, browser, `user4@standardsubdomainfes.localhost:${port}`); await ComposePageRecipe.fillMsg(composePage, { to: 'invalid@example.com', cc: 'to@example.com' }, subject); await composePage.waitAndType('@input-password', 'gO0d-pwd'); await composePage.waitAndClick('@action-send', { delay: 1 }); @@ -262,7 +262,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test await composePage.close(); expect((await GoogleData.withInitializedData(acct)).searchMessagesBySubject(subject).length).to.equal(++expectedNumberOfPassedMessages); // 4. "invalid To" Gmail error with all failures - composePage = await ComposePageRecipe.openStandalone(t, browser, 'user4@standardsubdomainfes.localhost:8001'); + composePage = await ComposePageRecipe.openStandalone(t, browser, `user4@standardsubdomainfes.localhost:${port}`); await ComposePageRecipe.fillMsg(composePage, { to: 'invalid@example.com', cc: 'cc@example.com' }, subject); await composePage.waitAndType('@input-password', 'gO0d-pwd'); await composePage.waitAndClick('@action-send', { delay: 1 }); @@ -274,7 +274,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test await composePage.close(); expect((await GoogleData.withInitializedData(acct)).searchMessagesBySubject(subject).length).to.equal(expectedNumberOfPassedMessages); // + 0 messages // 5. "RequestTimeout" error with partial success - composePage = await ComposePageRecipe.openStandalone(t, browser, 'user4@standardsubdomainfes.localhost:8001'); + composePage = await ComposePageRecipe.openStandalone(t, browser, `user4@standardsubdomainfes.localhost:${port}`); await ComposePageRecipe.fillMsg(composePage, { to: 'timeout@example.com', cc: 'to@example.com' }, subject); await composePage.waitAndType('@input-password', 'gO0d-pwd'); await composePage.waitAndClick('@action-send', { delay: 1 }); @@ -287,7 +287,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test await composePage.close(); expect((await GoogleData.withInitializedData(acct)).searchMessagesBySubject(subject).length).to.equal(++expectedNumberOfPassedMessages); // 6. "RequestTimeout" error with all failures - composePage = await ComposePageRecipe.openStandalone(t, browser, 'user4@standardsubdomainfes.localhost:8001'); + composePage = await ComposePageRecipe.openStandalone(t, browser, `user4@standardsubdomainfes.localhost:${port}`); await ComposePageRecipe.fillMsg(composePage, { to: 'timeout@example.com', cc: 'cc@example.com' }, subject); await composePage.waitAndType('@input-password', 'gO0d-pwd'); await composePage.waitAndClick('@action-send', { delay: 1 }); @@ -305,7 +305,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'user@forbid-storing-passphrase-client-configuration.flowcrypt.test - do not store passphrase', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'user@forbid-storing-passphrase-client-configuration.flowcrypt.test'; @@ -319,7 +319,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test { isSavePassphraseHidden: true, isSavePassphraseChecked: false } ); await settingsPage.notPresent('.swal2-container'); - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox(acctEmail)); + const inboxPage = await browser.newExtensionInboxPage(t, acctEmail); await InboxPageRecipe.finishSessionOnInboxPage(inboxPage); const composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await ComposePageRecipe.fillMsg(composeFrame, { to: 'human@flowcrypt.com' }, 'should not send as pass phrase is not known', undefined, { @@ -336,7 +336,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'standalone - different send from, new signed message, verification in mock', testWithBrowser('compatibility', async (t, browser) => { const key = Config.key('flowcryptcompatibility.from.address'); @@ -357,7 +357,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'compose - test compose after reconnect account', testWithBrowser('ci.tests.gmail', async (t, browser) => { const acct = 'ci.tests.gmail@flowcrypt.test'; @@ -377,7 +377,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'with attachments + shows progress %', testWithBrowser('compatibility', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility'); @@ -389,7 +389,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'compose > large file > public domain account (should not prompt to upgrade)', testWithBrowser('compatibility', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility'); @@ -402,7 +402,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'compose - PWD encrypted message with flowcrypt.com/shared-tenant-fes', testWithBrowser('compatibility', async (t, browser) => { const msgPwd = 'super hard password for the message'; @@ -417,10 +417,10 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'compose - load contacts - contacts should be properly ordered', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox('ci.tests.gmail@flowcrypt.test')); + const inboxPage = await browser.newExtensionInboxPage(t, 'ci.tests.gmail@flowcrypt.test'); let composeFrame = await InboxPageRecipe.openAndGetComposeFrame(inboxPage); await composeFrame.type('@input-to', 'testsearchorder'); if (testVariant === 'CONSUMER-MOCK') { @@ -478,7 +478,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default(`[unit][Stream.readToEnd] efficiently handles multiple chunks`, async t => { + test(`[unit][Stream.readToEnd] efficiently handles multiple chunks`, async t => { const stream = new ReadableStream({ // eslint-disable-next-line prefer-arrow/prefer-arrow-functions start(controller) { @@ -493,7 +493,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test t.pass(); }); - ava.default( + test( 'decrypt - entering pass phrase should unlock all keys that match the pass phrase', testWithBrowser('compatibility', async (t, browser) => { const acctEmail = 'flowcrypt.compatibility@gmail.com'; @@ -501,7 +501,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, testConstants.testkey17AD7D07, passphrase, {}, false); await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, testConstants.testkey0389D3A7, passphrase, {}, false); await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, testConstants.testKeyMultipleSmimeCEA2D53BB9D24871, passphrase, {}, false); - const inboxPage = await browser.newPage(t, TestUrls.extensionInbox(acctEmail)); + const inboxPage = await browser.newExtensionInboxPage(t, acctEmail); await InboxPageRecipe.finishSessionOnInboxPage(inboxPage); await InboxPageRecipe.checkDecryptMsg(t, browser, { acctEmail, diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index b17d2acf6d5..37c4d9dc546 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -1,6 +1,6 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ -import * as ava from 'ava'; +import test from 'ava'; import { expect } from 'chai'; import { BrowserHandle, ControllablePage } from './../browser'; @@ -108,7 +108,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test await gmailPage.goto(url); }; - ava.default( + test( 'mail.google.com/chat', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginButCloseOauthWindowBeforeGrantingPermission(t, browser, 'ci.tests.gmail@flowcrypt.dev'); @@ -118,7 +118,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - send rich-text encrypted message', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await BrowserRecipe.openGmailPageAndVerifyComposeBtnPresent(t, browser); @@ -137,7 +137,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - decrypt message in offline mode', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -161,7 +161,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - rendering attachmnents', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -172,7 +172,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - msg.asc message content renders', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -190,7 +190,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - Thunderbird signature [html] is recognized', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -216,7 +216,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - Thunderbird signature [plain] is recognized + correct height', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -242,7 +242,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - pubkey gets rendered with new signed and encrypted Thunderbird signature', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -264,7 +264,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - saving and rendering compose drafts when offline', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -292,7 +292,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - secure reply btn, reply draft', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -322,7 +322,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - multiple compose windows, saving/opening compose draft', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -346,7 +346,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - plain message contains smart replies', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -356,7 +356,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - plain reply to encrypted and signed messages', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -381,7 +381,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - switch to encrypted reply for middle message', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -400,7 +400,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - plain reply with dot menu', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -423,7 +423,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - plain reply draft', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -441,7 +441,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - Outlook encrypted message with attachment is recognized', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'ci.tests.gmail@flowcrypt.dev'); @@ -461,7 +461,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( `mail.google.com - simple attachments triggering processAttachments() keep "download all" button visible`, testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -473,7 +473,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( `mail.google.com - encrypted text inside "message" attachment`, testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'ci.tests.gmail@flowcrypt.dev'); @@ -493,7 +493,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( `mail.google.com - render plain text for "message" attachment (which has plain text)`, testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -507,7 +507,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'mail.google.com - pubkey file gets rendered', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser); @@ -519,7 +519,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test ); // uses live openpgpkey.flowcrypt.com WKD - ava.default( + test( 'can lookup public key from WKD directly', testWithBrowser('ci.tests.gmail', async (t, browser) => { const composePage = await ComposePageRecipe.openStandalone(t, browser, 'ci.tests.gmail@flowcrypt.dev'); @@ -530,7 +530,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test ); // todo - missing equivalent sample at ci.tests.gmail - // ava.default('mail.google.com - pubkey gets rendered when using quoted-printable mime', testWithBrowser('compatibility', async (t, browser) => { + // test('mail.google.com - pubkey gets rendered when using quoted-printable mime', testWithBrowser('compatibility', async (t, browser) => { // const gmailPage = await openGmailPage(t, browser, '/WhctKJVRFztXGwvSbwcrbDshGTnLWMFvhwJmhqllRWwvpKnlpblQMXVZLTsKfWdPWKhPFBV'); // const urls = await gmailPage.getFramesUrls(['/chrome/elements/pgp_pubkey.htm'], { sleep: 10, appearIn: 20 }); // expect(urls.length).to.equal(1); @@ -543,8 +543,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test const testMinimumElementHeight = async (page: ControllablePage, selector: string, min: number) => { // testing https://github.com/FlowCrypt/flowcrypt-browser/issues/3519 const elStyle = await page.target.$eval(selector, el => el.getAttribute('style')); // 'height: 289.162px;' - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const elHeight = Number(elStyle!.replace('height: ', '').replace('px;', '')); + const elHeight = Number(elStyle?.replace('height: ', '').replace('px;', '')); if (isNaN(elHeight)) { throw Error(`msgIframeHeight iNaN`); } diff --git a/test/source/tests/page-recipe/abstract-page-recipe.ts b/test/source/tests/page-recipe/abstract-page-recipe.ts index d9d7e981b46..a9c0f73bf85 100644 --- a/test/source/tests/page-recipe/abstract-page-recipe.ts +++ b/test/source/tests/page-recipe/abstract-page-recipe.ts @@ -35,8 +35,7 @@ export abstract class PageRecipe { } if (clickOn) { const button = await modalContainer.$(`button.ui-modal-${type}-${clickOn}`); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - await button!.click(); + await button?.click(); } }; diff --git a/test/source/tests/page-recipe/inbox-page-recipe.ts b/test/source/tests/page-recipe/inbox-page-recipe.ts index 2c7a782d227..4fce7b92bc0 100644 --- a/test/source/tests/page-recipe/inbox-page-recipe.ts +++ b/test/source/tests/page-recipe/inbox-page-recipe.ts @@ -4,7 +4,6 @@ import { BrowserHandle, ControllableFrame, ControllablePage } from '../../browse import { AvaContext } from '../tooling/'; import { PageRecipe } from './abstract-page-recipe'; -import { TestUrls } from '../../browser/test-urls'; import { Util } from '../../util'; import { expect } from 'chai'; @@ -30,7 +29,7 @@ export class InboxPageRecipe extends PageRecipe { browser: BrowserHandle, { acctEmail, threadId, enterPp, expectedContent, finishCurrentSession }: CheckDecryptMsg$opt ) => { - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe'); if (finishCurrentSession) { await InboxPageRecipe.finishSessionOnInboxPage(inboxPage); @@ -77,7 +76,7 @@ export class InboxPageRecipe extends PageRecipe { }; public static checkFinishingSession = async (t: AvaContext, browser: BrowserHandle, acctEmail: string, threadId: string) => { - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await InboxPageRecipe.finishSessionOnInboxPage(inboxPage); await inboxPage.waitAll('iframe'); const pgpBlockFrame = await inboxPage.getFrame(['pgp_block.htm']); @@ -101,7 +100,7 @@ export class InboxPageRecipe extends PageRecipe { if (typeof isEncrypted !== 'undefined') { throw new Error('checkSentMsg.isEncrypted not implemented'); } - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&labelId=SENT`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&labelId=SENT`); await inboxPage.waitAndClick(`@container-subject(${subject})`, { delay: 1 }); if (sender) { // make sure it was sent from intended addr diff --git a/test/source/tests/page-recipe/oauth-page-recipe.ts b/test/source/tests/page-recipe/oauth-page-recipe.ts index 190282d0cf4..c3e13e2ab74 100644 --- a/test/source/tests/page-recipe/oauth-page-recipe.ts +++ b/test/source/tests/page-recipe/oauth-page-recipe.ts @@ -46,7 +46,7 @@ export class OauthPageRecipe extends PageRecipe { action: 'close' | 'deny' | 'approve' | 'login' | 'login_with_invalid_state' ): Promise => { try { - const isMock = oauthPage.target.url().includes('localhost') || oauthPage.target.url().includes('google.mock.localhost'); + const isMock = oauthPage.target.url().includes('localhost'); if (isMock) { await OauthPageRecipe.mock(t, oauthPage, acctEmail, action); return; diff --git a/test/source/tests/page-recipe/settings-page-recipe.ts b/test/source/tests/page-recipe/settings-page-recipe.ts index 49eecf56b11..795da2867ba 100644 --- a/test/source/tests/page-recipe/settings-page-recipe.ts +++ b/test/source/tests/page-recipe/settings-page-recipe.ts @@ -7,7 +7,6 @@ import { PageRecipe } from './abstract-page-recipe'; import { assert, expect } from 'chai'; import { Str } from '../../core/common'; import { AvaContext } from '../tooling'; -import { TestUrls } from '../../browser/test-urls'; import { Xss } from '../../platform/xss'; import { Key, KeyUtil } from '../../core/crypto/key'; import { readFileSync } from 'fs'; @@ -147,8 +146,7 @@ export class SettingsPageRecipe extends PageRecipe { } else { assert(false); } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const fp = Str.spaced(Xss.escape(key!.id)); + const fp = Str.spaced(Xss.escape(key.id)); await addPrvPage.waitAndClick('#toggle_input_passphrase'); await addPrvPage.waitAndType('#input_passphrase', passphrase); if (checks.isSavePassphraseHidden !== undefined) { @@ -165,7 +163,7 @@ export class SettingsPageRecipe extends PageRecipe { await Util.sleep(2); await addPrvPage.close(); await Util.sleep(2); - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acctEmail)); + const settingsPage = await browser.newExtensionSettingsPage(t, acctEmail); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); await settingsPage.waitForContent('@container-settings-keys-list', fp); // confirm key successfully loaded await settingsPage.close(); diff --git a/test/source/tests/settings.ts b/test/source/tests/settings.ts index b53df65fa6a..6fdbe87b27b 100644 --- a/test/source/tests/settings.ts +++ b/test/source/tests/settings.ts @@ -1,7 +1,7 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ import * as fs from 'fs'; -import * as ava from 'ava'; +import test from 'ava'; import { Config, Util } from './../util'; import { TestWithBrowser, internalTestState } from './../test'; @@ -9,7 +9,6 @@ import { TestWithBrowser, internalTestState } from './../test'; import { BrowserRecipe } from './tooling/browser-recipe'; import { InboxPageRecipe } from './page-recipe/inbox-page-recipe'; import { SettingsPageRecipe } from './page-recipe/settings-page-recipe'; -import { TestUrls } from './../browser/test-urls'; import { TestVariant } from './../util'; import { expect } from 'chai'; import { SetupPageRecipe } from './page-recipe/setup-page-recipe'; @@ -29,10 +28,10 @@ import { HttpClientErr, Status } from '../mock/lib/api'; export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: TestWithBrowser) => { if (testVariant !== 'CONSUMER-LIVE-GMAIL') { - ava.default( + test( 'settings - my own emails show as contacts', testWithBrowser('compatibility', async (t, browser) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('flowcrypt.compatibility@gmail.com')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'flowcrypt.compatibility@gmail.com'); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const comtactsFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-contacts-page', ['contacts.htm', 'placement=settings']); await comtactsFrame.waitAll('@page-contacts'); @@ -43,10 +42,10 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await SettingsPageRecipe.toggleScreen(settingsPage, 'basic'); }) ); - ava.default( + test( 'settings - attester shows my emails', testWithBrowser('compatibility', async (t, browser) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('flowcrypt.compatibility@gmail.com')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'flowcrypt.compatibility@gmail.com'); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const attesterFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-attester-page', ['keyserver.htm', 'placement=settings']); await attesterFrame.waitAll('@page-attester'); @@ -58,7 +57,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await SettingsPageRecipe.toggleScreen(settingsPage, 'basic'); }) ); - ava.default( + test( 'settings - attester diagnostics page shows mismatch information correctly', testWithBrowser(undefined, async (t, browser) => { const email = 'test.match.attester.key@gmail.com'; @@ -81,32 +80,31 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T ); }) ); - ava.default( + test( 'settings - verify key presense 1pp1', testWithBrowser('compatibility', async (t, browser) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('flowcrypt.compatibility@gmail.com')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'flowcrypt.compatibility@gmail.com'); await SettingsPageRecipe.verifyMyKeyPage(settingsPage, 'flowcrypt.compatibility.1pp1', 'button'); }) ); - ava.default( + test( 'settings - test pass phrase', testWithBrowser('compatibility', async (t, browser) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('flowcrypt.compatibility@gmail.com')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'flowcrypt.compatibility@gmail.com'); await SettingsPageRecipe.passphraseTest(settingsPage, Config.key('flowcrypt.wrong.passphrase').passphrase, false); await SettingsPageRecipe.passphraseTest(settingsPage, Config.key('flowcrypt.compatibility.1pp1').passphrase, true); }) ); - ava.default( + test( 'settings - clarify passphrase prompt text', testWithBrowser('compatibility', async (t, browser) => { const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acctEmail)); + const settingsPage = await browser.newExtensionSettingsPage(t, acctEmail); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const fingerprint = (await settingsPage.read('.good')).split(' ').join(''); const longid = OpenPGPKey.fingerprintToLongid(fingerprint); const baseUrl = `chrome/elements/passphrase.htm?acctEmail=${acctEmail}&longids=${longid}&parentTabId=`; - let passphrasePage; - passphrasePage = await browser.newPage(t, baseUrl.concat('&type=sign')); + let passphrasePage = await browser.newPage(t, baseUrl.concat('&type=sign')); await passphrasePage.waitForSelTestState('ready'); expect(await passphrasePage.read('@passphrase-text')).to.equal('Enter FlowCrypt pass phrase to sign email'); await passphrasePage.close(); @@ -132,12 +130,12 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await passphrasePage.close(); }) ); - ava.default.todo('settings - verify 2pp1 key presense'); + test.todo('settings - verify 2pp1 key presense'); // await tests.settings_my_key_tests(settingsPage, 'flowcrypt.compatibility.2pp1', 'link'); - ava.default( + test( 'settings - feedback form', testWithBrowser('compatibility', async (t, browser) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('flowcrypt.compatibility@gmail.com')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'flowcrypt.compatibility@gmail.com'); await settingsPage.waitAndClick('@action-open-modules-help'); await settingsPage.waitAll('@dialog'); const helpFrame = await settingsPage.getFrame(['help.htm']); @@ -146,10 +144,10 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await helpFrame.waitAndRespondToModal('info', 'confirm', 'Message sent!'); }) ); - ava.default( + test( 'settings - view contact public key', testWithBrowser('compatibility', async (t, browser) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('flowcrypt.compatibility@gmail.com')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'flowcrypt.compatibility@gmail.com'); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const contactsFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-contacts-page', ['contacts.htm', 'placement=settings']); await contactsFrame.waitAll('@page-contacts'); @@ -174,12 +172,12 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await SettingsPageRecipe.toggleScreen(settingsPage, 'basic'); }) ); - ava.default( + test( 'settings - update contact public key', testWithBrowser('ci.tests.gmail', async (t, browser) => { const recipientEmail = 'has.older.key.on.attester@recipient.com'; // add a newer expired key manually - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('ci.tests.gmail@flowcrypt.test')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'ci.tests.gmail@flowcrypt.test'); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const contactsFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-contacts-page', ['contacts.htm', 'placement=settings']); await contactsFrame.waitAll('@page-contacts'); @@ -219,10 +217,10 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await contactsFrame.waitForContent('@container-pubkey-details', 'Expired: yes'); }) ); - ava.default( + test( 'settings - import revoked key fails but the revocation info is saved', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const dbPage = await browser.newPage(t, TestUrls.extension('chrome/dev/ci_unit_test.htm')); + const dbPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); const revocationBefore = await dbPage.page.evaluate(async () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const db = await (window as any).ContactStore.dbOpen(); @@ -235,7 +233,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T return revocation; }); expect(revocationBefore).to.be.an('undefined'); // no revocations yet - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('ci.tests.gmail@flowcrypt.test')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'ci.tests.gmail@flowcrypt.test'); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const contactsFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-contacts-page', ['contacts.htm', 'placement=settings']); await contactsFrame.waitAll('@page-contacts'); @@ -261,10 +259,10 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T expect(revocationAfter).not.to.be.an('undefined'); // revocation is saved in the database }) ); - ava.default( + test( 'settings - remove public keys from contact', testWithBrowser('compatibility', async (t, browser) => { - const dbPage = await browser.newPage(t, TestUrls.extension('chrome/dev/ci_unit_test.htm')); + const dbPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); const foundKeys = await dbPage.page.evaluate(async () => { /* eslint-disable @typescript-eslint/no-explicit-any */ const db = await (window as any).ContactStore.dbOpen(); @@ -301,7 +299,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T expect(foundKeys.contactsSize).to.equal(1); expect(foundKeys.pubkey7FDE685548AEA788.fingerprint).to.equal('5520CACE2CB61EA713E5B0057FDE685548AEA788'); expect(foundKeys.pubkeyADAC279C95093207.fingerprint).to.equal('E8F0517BA6D7DAB6081C96E4ADAC279C95093207'); - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('flowcrypt.compatibility@gmail.com')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'flowcrypt.compatibility@gmail.com'); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const contactsFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-contacts-page', ['contacts.htm', 'placement=settings']); await contactsFrame.waitAll('@page-contacts'); @@ -382,18 +380,18 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await dbPage.close(); }) ); - ava.default( + test( 'settings - my key page - primary + secondary', testWithBrowser('compatibility', async (t, browser) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('flowcrypt.compatibility@gmail.com')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'flowcrypt.compatibility@gmail.com'); await SettingsPageRecipe.verifyMyKeyPage(settingsPage, 'flowcrypt.compatibility.1pp1', 'link', 0); await SettingsPageRecipe.verifyMyKeyPage(settingsPage, 'flowcrypt.compatibility.2pp1', 'link', 1); }) ); - ava.default( + test( 'settings - my key page - remove key', testWithBrowser('compatibility', async (t, browser) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('flowcrypt.compatibility@gmail.com')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'flowcrypt.compatibility@gmail.com'); await SettingsPageRecipe.ready(settingsPage); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); await settingsPage.waitAll('@action-open-add-key-page'); @@ -404,7 +402,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await settingsPage.notPresent('@action-remove-key-0'); }) ); - ava.default( + test( 'settings - my key page - privileged frames and action buttons should be hidden when using key manager test', testWithBrowser(undefined, async (t, browser) => { const acct = 'two.keys@key-manager-autogen.flowcrypt.test'; @@ -421,21 +419,18 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await settingsPage.notPresent('@action-remove-key-0'); const fingerprint = await myKeyFrame.readHtml('@content-fingerprint'); // test for direct access at my_key_update.htm - const myKeyUpdateFrame = await browser.newPage( + const myKeyUpdateFrame = await browser.newExtensionPage( t, - TestUrls.extension(`chrome/settings/modules/my_key_update.htm?placement=settings&acctEmail=${acct}&fingerprint=${fingerprint}`) + `chrome/settings/modules/my_key_update.htm?placement=settings&acctEmail=${acct}&fingerprint=${fingerprint}` ); await myKeyUpdateFrame.waitForContent('@container-err-title', 'Error: Insufficient Permission'); // test for direct access at my add_key.htm - const addKeyFrame = await browser.newPage( - t, - TestUrls.extension(`chrome/settings/modules/add_key.htm?placement=settings&acctEmail=${acct}&parentTabId=1`) - ); + const addKeyFrame = await browser.newExtensionPage(t, `chrome/settings/modules/add_key.htm?placement=settings&acctEmail=${acct}&parentTabId=1`); await addKeyFrame.waitForContent('@container-err-text', 'Please contact your IT staff if you wish to update your keys'); }) ); - ava.default.todo('settings - edit contact public key'); - ava.default( + test.todo('settings - edit contact public key'); + test( 'settings - change passphrase - current in local storage', testWithBrowser(undefined, async (t, browser) => { const { acctEmail, settingsPage } = await BrowserRecipe.setUpFcPpChangeAcct(t, browser); @@ -448,7 +443,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T }); }) ); - ava.default( + test( 'settings - change passphrase - current in session known', testWithBrowser(undefined, async (t, browser) => { const { acctEmail, passphrase, settingsPage } = await BrowserRecipe.setUpFcPpChangeAcct(t, browser); @@ -487,7 +482,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T }); }) ); - ava.default( + test( 'settings - change passphrase honoring FORBID_STORING_PASS_PHRASE ClientConfiguration', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'user@forbid-storing-passphrase-client-configuration.flowcrypt.test'; @@ -534,7 +529,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T }); }) ); - ava.default( + test( 'settings - change passphrase - current in session unknown', testWithBrowser(undefined, async (t, browser) => { const { acctEmail, passphrase, settingsPage } = await BrowserRecipe.setUpFcPpChangeAcct(t, browser); @@ -558,22 +553,22 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T }); }) ); - ava.default( + test( 'settings - Catch.reportErr reports an error', testWithBrowser('compatibility', async (t, browser) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('flowcrypt.compatibility@gmail.com')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'flowcrypt.compatibility@gmail.com'); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const experimentalFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-module-experimental', ['experimental.htm']); await experimentalFrame.waitAndClick('@action-throw-err'); // mock tests will verify that err was reported to mock backend in `test.ts` internalTestState.expectIntentionalErrReport = true; }) ); - ava.default( + test( 'settings - attachment previews are rendered according to their types', testWithBrowser('compatibility', async (t, browser) => { - const inboxPage = await browser.newPage( + const inboxPage = await browser.newExtensionPage( t, - TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=174ab0ba9643b4fa`) + `chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=174ab0ba9643b4fa` ); // image const attachmentImage = await inboxPage.getFrame(['attachment.htm', 'name=tiny-face.png']); @@ -605,15 +600,15 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await attachmentPreviewOther.waitAll('#attachment-preview-container .attachment-preview-unavailable #attachment-preview-download'); }) ); - ava.default( + test( 'settings - attachment previews with entering pass phrase', testWithBrowser('compatibility', async (t, browser) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('flowcrypt.compatibility@gmail.com')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'flowcrypt.compatibility@gmail.com'); const k = Config.key('flowcrypt.compatibility.1pp1'); await SettingsPageRecipe.forgetAllPassPhrasesInStorage(settingsPage, k.passphrase); - const inboxPage = await browser.newPage( + const inboxPage = await browser.newExtensionPage( t, - TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=174ab0ba9643b4fa`) + `chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=174ab0ba9643b4fa` ); const attachmentImage = await inboxPage.getFrame(['attachment.htm', 'name=tiny-face.png']); await attachmentImage.waitForSelTestState('ready'); @@ -625,14 +620,14 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await attachmentPreviewImage.waitAll('#attachment-preview-container img.attachment-preview-img'); }) ); - ava.default( + test( 'settings - pgp/mime preview and download attachment', testWithBrowser('compatibility', async (t, browser) => { const downloadedAttachmentFilename = `${__dirname}/7 years.jpeg`; Util.deleteFileIfExists(downloadedAttachmentFilename); - const inboxPage = await browser.newPage( + const inboxPage = await browser.newExtensionPage( t, - TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=16e8b01f136c3d28`) + `chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=16e8b01f136c3d28` ); const pgpBlockFrame = await inboxPage.getFrame(['pgp_block.htm']); // check if download is awailable @@ -651,10 +646,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T }) ); const checkIfFileDownloadsCorrectly = async (t: AvaContext, browser: BrowserHandle, threadId: string, fileName: string) => { - const inboxPage = await browser.newPage( - t, - TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=${threadId}`) - ); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=${threadId}`); const attachment = await inboxPage.getFrame(['attachment.htm']); const downloadedFiles = await inboxPage.awaitDownloadTriggeredByClicking(async () => { await attachment.waitAndClick('@download-attachment'); @@ -662,7 +654,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T expect(Object.keys(downloadedFiles)).contains(fileName); await inboxPage.close(); }; - ava.default( + test( 'settings - check if downloaded attachment name is correct', testWithBrowser('compatibility', async (t, browser) => { // `what's up?.txt` becomes `what's_up_.txt` and this is native way and we can't change this logic @@ -671,7 +663,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await checkIfFileDownloadsCorrectly(t, browser, '182263bf9f105adf', "what's_up%253F.txt"); }) ); - ava.default( + test( 'settings - add unprotected key', testWithBrowser('ci.tests.gmail', async (t, browser) => { await SettingsPageRecipe.addKeyTest( @@ -684,7 +676,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T ); }) ); - ava.default( + test( 'settings - add unprotected s/mime key', testWithBrowser('ci.tests.gmail', async (t, browser) => { const unprotectedPrvKey = fs.readFileSync('test/samples/smime/human-unprotected-pem.txt', 'utf8'); @@ -698,18 +690,15 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T ); }) ); - ava.default( + test( 'settings - error modal when page parameter invalid', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const invalidParamModalPage = await browser.newPage( - t, - TestUrls.extension(`chrome/settings/index.htm?acctEmail=ci.tests.gmail@flowcrypt.test&page=invalid`) - ); + const invalidParamModalPage = await browser.newExtensionPage(t, `chrome/settings/index.htm?acctEmail=ci.tests.gmail@flowcrypt.test&page=invalid`); await Util.sleep(3); await invalidParamModalPage.waitForContent('.swal2-html-container', 'An unexpected value was found for the page parameter'); }) ); - ava.default( + test( 'settings - my key page - update non-first private key', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.test.key.multiple@gmail.com'; @@ -734,7 +723,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T isSavePassphraseChecked: true, isSavePassphraseHidden: false, }); - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acctEmail)); + const settingsPage = await browser.newExtensionSettingsPage(t, acctEmail); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); // open key at index 1 const myKeyFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, `@action-show-key-1`, ['my_key.htm', 'placement=settings']); @@ -755,7 +744,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await settingsPage.close(); }) ); - ava.default( + test( 'settings - manual backup several keys to file with the same pass phrase', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.test.key.multiple@gmail.com'; @@ -789,9 +778,9 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T isSavePassphraseHidden: false, }); // opening backup.htm independently of settings/index.htm page limits functionality but sufficient for this test - const backupPage = await browser.newPage( + const backupPage = await browser.newExtensionPage( t, - TestUrls.extension(`/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}&action=backup_manual&parentTabId=1%3A0`) + `/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}&action=backup_manual&parentTabId=1%3A0` ); // OpenPGP keys are checked, x509 keys are unchecked expect(await backupPage.isChecked('[data-id="47FB03183E03A8ED44E3BBFCCEA2D53BB9D24871"]')).to.equal(false); @@ -825,7 +814,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await backupPage.close(); }) ); - ava.default( + test( 'settings - manual backup several keys to inbox with the same strong pass phrase', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.test.key.multiple.inbox2@gmail.com'; @@ -852,9 +841,9 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T isSavePassphraseHidden: false, }); // opening backup.htm independently of settings/index.htm page limits functionality but sufficient for this test - const backupPage = await browser.newPage( + const backupPage = await browser.newExtensionPage( t, - TestUrls.extension(`/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}&action=backup_manual&parentTabId=1%3A0`) + `/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}&action=backup_manual&parentTabId=1%3A0` ); expect(await backupPage.isChecked('[data-id="CB0485FE44FC22FF09AF0DB31B383D0334E38B28"]')).to.equal(true); expect(await backupPage.isChecked('[data-id="515431151DDD3EA232B37A4C98ACFA1EADAB5B92"]')).to.equal(true); @@ -862,8 +851,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T expect(await backupPage.isDisabled('[data-id="515431151DDD3EA232B37A4C98ACFA1EADAB5B92"]')).to.equal(false); await backupPage.waitAndClick('@action-backup-step3manual-continue'); await backupPage.waitAndRespondToModal('info', 'confirm', 'Your private keys have been successfully backed up'); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const sentMsg = (await GoogleData.withInitializedData(acctEmail)).searchMessagesBySubject('Your FlowCrypt Backup')[0]!; + const sentMsg = (await GoogleData.withInitializedData(acctEmail)).searchMessagesBySubject('Your FlowCrypt Backup')[0]; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const mimeMsg = await Parse.convertBase64ToMimeMsg(sentMsg.raw!); const { keys } = await KeyUtil.readMany(Buf.concat(mimeMsg.attachments.map(a => a.content))); @@ -871,7 +859,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await backupPage.close(); }) ); - ava.default( + test( 'settings - manual backup several keys to file with a missing but guessed pass phrase', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.test.key.multiple@gmail.com'; @@ -892,16 +880,16 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T { isSavePassphraseChecked: false, isSavePassphraseHidden: false } ); await settingsPage.close(); - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}`); await InboxPageRecipe.finishSessionOnInboxPage(inboxPage); await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, testConstants.testKeyMultiple98acfa1eadab5b92, '1234', { isSavePassphraseChecked: true, isSavePassphraseHidden: false, }); // opening backup.htm independently of settings/index.htm page limits functionality but sufficient for this test - const backupPage = await browser.newPage( + const backupPage = await browser.newExtensionPage( t, - TestUrls.extension(`/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}` + `&action=backup_manual&parentTabId=1%3A0`) + `/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}` + `&action=backup_manual&parentTabId=1%3A0` ); expect(await backupPage.isChecked('[data-id="CB0485FE44FC22FF09AF0DB31B383D0334E38B28"]')).to.equal(true); expect(await backupPage.isChecked('[data-id="515431151DDD3EA232B37A4C98ACFA1EADAB5B92"]')).to.equal(true); @@ -924,7 +912,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await backupPage.close(); }) ); - ava.default( + test( 'settings - manual backup several keys to inbox with a missing pass phrase', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.test.key.multiple@gmail.com'; @@ -944,7 +932,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T }, { isSavePassphraseChecked: false, isSavePassphraseHidden: false } ); - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}`); await InboxPageRecipe.finishSessionOnInboxPage(inboxPage); await inboxPage.close(); const key98acfa1eadab5b92 = await KeyUtil.parse(testConstants.testKeyMultiple98acfa1eadab5b92); @@ -965,7 +953,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await settingsPage.close(); }) ); - ava.default( + test( 'settings - manual backup a key with a missing pass phrase', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.test.key.multiple@gmail.com'; @@ -982,7 +970,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T { submitPubkey: false, usedPgpBefore: false, key }, { isSavePassphraseChecked: false, isSavePassphraseHidden: false } ); - const inboxPage = await browser.newPage(t, TestUrls.extension(`chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}`)); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}`); await InboxPageRecipe.finishSessionOnInboxPage(inboxPage); await inboxPage.close(); await settingsPage.waitAndClick('@action-open-backup-page'); @@ -998,7 +986,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await settingsPage.close(); }) ); - ava.default( + test( 'settings - manual backup several keys to file with different pass phrases', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.test.key.multiple@gmail.com'; @@ -1026,9 +1014,9 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T isSavePassphraseHidden: false, }); // opening backup.htm independently of settings/index.htm page limits functionality but sufficient for this test - const backupPage = await browser.newPage( + const backupPage = await browser.newExtensionPage( t, - TestUrls.extension(`/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}&action=backup_manual&parentTabId=1%3A0`) + `/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}&action=backup_manual&parentTabId=1%3A0` ); expect(await backupPage.isChecked('[data-id="CB0485FE44FC22FF09AF0DB31B383D0334E38B28"]')).to.equal(true); expect(await backupPage.isChecked('[data-id="515431151DDD3EA232B37A4C98ACFA1EADAB5B92"]')).to.equal(true); @@ -1040,7 +1028,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await backupPage.close(); }) ); - ava.default( + test( 'settings - setup_manual only backs up supplied key to file', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.test.key.multiple@gmail.com'; @@ -1065,12 +1053,10 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T isSavePassphraseChecked: true, isSavePassphraseHidden: false, }); - const backupPage = await browser.newPage( + const backupPage = await browser.newExtensionPage( t, - TestUrls.extension( - `/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}&action=backup_manual&parentTabId=1%3A0` + - '&type=openpgp&id=515431151DDD3EA232B37A4C98ACFA1EADAB5B92&idToken=fakeheader.01' - ) + `/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}&action=backup_manual&parentTabId=1%3A0` + + '&type=openpgp&id=515431151DDD3EA232B37A4C98ACFA1EADAB5B92&idToken=fakeheader.01' ); await backupPage.waitAndClick('@input-backup-step3manual-file'); const downloadedFiles = await backupPage.awaitDownloadTriggeredByClicking('@action-backup-step3manual-continue'); @@ -1086,7 +1072,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await backupPage.close(); }) ); - ava.default( + test( 'settings - setup_manual only backs up supplied key to inbox', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.test.key.multiple.inbox1@gmail.com'; @@ -1115,26 +1101,24 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T isSavePassphraseChecked: true, isSavePassphraseHidden: false, }); - const backupPage = await browser.newPage( + const backupPage = await browser.newExtensionPage( t, - TestUrls.extension( - `/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}&action=backup_manual&parentTabId=17%3A0` + - '&type=openpgp&id=515431151DDD3EA232B37A4C98ACFA1EADAB5B92&idToken=fakeheader.01' - ) + `/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}&action=backup_manual&parentTabId=17%3A0` + + '&type=openpgp&id=515431151DDD3EA232B37A4C98ACFA1EADAB5B92&idToken=fakeheader.01' ); await backupPage.waitAndClick('@action-backup-step3manual-continue'); await backupPage.waitAndRespondToModal('info', 'confirm', 'Your private key has been successfully backed up'); - /* eslint-disable @typescript-eslint/no-non-null-assertion */ - const sentMsg = (await GoogleData.withInitializedData(acctEmail)).searchMessagesBySubject('Your FlowCrypt Backup')[0]!; + + const sentMsg = (await GoogleData.withInitializedData(acctEmail)).searchMessagesBySubject('Your FlowCrypt Backup')[0]; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const mimeMsg = await Parse.convertBase64ToMimeMsg(sentMsg.raw!); - const { keys } = await KeyUtil.readMany(new Buf(mimeMsg.attachments[0]!.content!)); - /* eslint-enable @typescript-eslint/no-non-null-assertion */ + const { keys } = await KeyUtil.readMany(new Buf(mimeMsg.attachments[0].content)); expect(keys.length).to.equal(1); expect(KeyUtil.identityEquals(keys[0], { id: '515431151DDD3EA232B37A4C98ACFA1EADAB5B92', family: 'openpgp' })).to.equal(true); await backupPage.close(); }) ); - ava.default( + test( 'settings - manual backup to inbox keys with weak pass phrases results in error', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.test.key.multiple@gmail.com'; @@ -1160,9 +1144,9 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T isSavePassphraseHidden: false, }); // opening backup.htm independently of settings/index.htm page limits functionality but sufficient for this test - const backupPage = await browser.newPage( + const backupPage = await browser.newExtensionPage( t, - TestUrls.extension(`/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}&action=backup_manual&parentTabId=1%3A0`) + `/chrome/settings/modules/backup.htm?acctEmail=${acctEmail}&action=backup_manual&parentTabId=1%3A0` ); expect(await backupPage.isChecked('[data-id="CB0485FE44FC22FF09AF0DB31B383D0334E38B28"]')).to.equal(true); expect(await backupPage.isChecked('[data-id="515431151DDD3EA232B37A4C98ACFA1EADAB5B92"]')).to.equal(true); @@ -1175,7 +1159,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await backupPage.close(); }) ); - ava.default( + test( 'settings - manual enter and key update honor FORBID_STORING_PASS_PHRASE ClientConfiguration', testWithBrowser(undefined, async (t, browser) => { const { settingsPage, passphrase } = await BrowserRecipe.setUpFcForbidPpStoringAcct(t, browser); @@ -1207,12 +1191,12 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await settingsPage.close(); }) ); - ava.default( + test( 'settings - email change', testWithBrowser('ci.tests.gmail', async (t, browser) => { const acct1 = 'ci.tests.gmail@flowcrypt.test'; const acct2 = 'user@default-remember-passphrase-client-configuration.flowcrypt.test'; - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acct1)); + const settingsPage = await browser.newExtensionSettingsPage(t, acct1); const { cryptup_citestsgmailflowcrypttest_rules: oldRules, cryptup_citestsgmailflowcrypttest_passphrase_07481C8ACF9D49FE: savedPassphrase1 } = await settingsPage.getFromLocalStorage(['cryptup_citestsgmailflowcrypttest_rules', 'cryptup_citestsgmailflowcrypttest_passphrase_07481C8ACF9D49FE']); expect(savedPassphrase1).not.to.be.an('undefined'); @@ -1256,12 +1240,13 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await settingsPage.close(); }) ); - ava.default( + test( 'settings - ensure gracious behavior & ui should remain functional when updating client configuration', testWithBrowser(undefined, async (t, browser) => { + const port = t.urls?.port; const domain = 'settings.flowcrypt.test'; const acct = `test-update@${domain}`; - mockBackendData.clientConfigurationForDomain[domain] = keyManagerAutogenRules; + mockBackendData.clientConfigurationForDomain[domain] = keyManagerAutogenRules(`${t.urls?.port}`); const setupPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, acct); await SetupPageRecipe.autoSetupWithEKM(setupPage); const { cryptup_testupdatesettingsflowcrypttest_rules: rules1 } = await setupPage.getFromLocalStorage([ @@ -1277,20 +1262,20 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T ]); expect(clientConfiguration1.disallow_attester_search_for_domains).to.eql([]); expect(clientConfiguration1.enforce_keygen_algo).to.equal('rsa2048'); - expect(clientConfiguration1.key_manager_url).to.equal('https://localhost:8001/flowcrypt-email-key-manager'); + expect(clientConfiguration1.key_manager_url).to.equal(`https://localhost:${port}/flowcrypt-email-key-manager`); const accessToken = await BrowserRecipe.getGoogleAccessToken(setupPage, acct); await setupPage.close(); // Set invalid client configuration and check if it ensures gracious behavior & ui remain functional mockBackendData.clientConfigurationForDomain[domain] = { // flags is required but don't return it (to mock invalid client configuration) - key_manager_url: 'https://localhost:8001/flowcrypt-email-key-manager', // eslint-disable-line @typescript-eslint/naming-convention + key_manager_url: `https://localhost:${port}/flowcrypt-email-key-manager`, // eslint-disable-line @typescript-eslint/naming-convention }; const extraAuthHeaders = { Authorization: `Bearer ${accessToken}` }; // eslint-disable-line @typescript-eslint/naming-convention - const gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + const gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); const errorMsg = 'Failed to update FlowCrypt Client Configuration: Missing client configuration flags.'; await PageRecipe.waitForToastToAppearAndDisappear(gmailPage, errorMsg); // Ensure previous client configuration remains same - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acct)); + const settingsPage = await browser.newExtensionSettingsPage(t, acct); await PageRecipe.waitForToastToAppearAndDisappear(settingsPage, errorMsg); const { cryptup_testupdatesettingsflowcrypttest_rules: rules2 } = await settingsPage.getFromLocalStorage([ 'cryptup_testupdatesettingsflowcrypttest_rules', @@ -1305,12 +1290,13 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T ]); expect(clientConfiguration2.disallow_attester_search_for_domains).to.eql([]); expect(clientConfiguration2.enforce_keygen_algo).to.equal('rsa2048'); - expect(clientConfiguration2.key_manager_url).to.equal('https://localhost:8001/flowcrypt-email-key-manager'); + expect(clientConfiguration2.key_manager_url).to.equal(`https://localhost:${port}/flowcrypt-email-key-manager`); }) ); - ava.default( + test( 'settings - client configuration gets updated on settings and content script reloads', testWithBrowser(undefined, async (t, browser) => { + const port = t.urls?.port; const domain = 'settings.flowcrypt.test'; const acct = 'settings@settings.flowcrypt.test'; /* eslint-disable @typescript-eslint/naming-convention */ @@ -1318,7 +1304,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T mockBackendData.clientConfigurationForDomain[domain] = { flags: ['NO_PRV_BACKUP', 'ENFORCE_ATTESTER_SUBMIT', 'PRV_AUTOIMPORT_OR_AUTOGEN', 'PASS_PHRASE_QUIET_AUTOGEN', 'DEFAULT_REMEMBER_PASS_PHRASE'], // custom_keyserver_url: undefined, - key_manager_url: 'https://localhost:8001/flowcrypt-email-key-manager', + key_manager_url: `https://localhost:${port}/flowcrypt-email-key-manager`, // allow_attester_search_only_for_domains: undefined, disallow_attester_search_for_domains: ['disallowed_domain1.test', 'disallowed_domain2.test'], enforce_keygen_algo: 'rsa2048', @@ -1341,13 +1327,13 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T expect(clientConfiguration1.enforce_keygen_algo).to.equal('rsa2048'); expect(clientConfiguration1.enforce_keygen_expire_months).to.be.an.undefined; expect(clientConfiguration1.custom_keyserver_url).to.be.an.undefined; - expect(clientConfiguration1.key_manager_url).to.equal('https://localhost:8001/flowcrypt-email-key-manager'); + expect(clientConfiguration1.key_manager_url).to.equal(`https://localhost:${port}/flowcrypt-email-key-manager`); await setupPage.close(); // modify the setup /* eslint-disable @typescript-eslint/naming-convention */ mockBackendData.clientConfigurationForDomain[domain] = { flags: ['NO_ATTESTER_SUBMIT', 'HIDE_ARMOR_META', 'DEFAULT_REMEMBER_PASS_PHRASE'], - custom_keyserver_url: 'https://localhost:8001', + custom_keyserver_url: `https://localhost:${port}`, // key_manager_url: undefined, allow_attester_search_only_for_domains: ['allowed_domain1.test', 'allowed_domain2.test'], // disallow_attester_search_for_domains: undefined @@ -1356,12 +1342,12 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T }; /* eslint-enable @typescript-eslint/naming-convention */ // open the settings page - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acct)); + const settingsPage = await browser.newExtensionSettingsPage(t, acct); const { cryptup_settingssettingsflowcrypttest_rules: rules2 } = await settingsPage.getFromLocalStorage(['cryptup_settingssettingsflowcrypttest_rules']); // check that the configuration in the storage has been updated const clientConfiguration2 = rules2 as ClientConfiguration; expect(clientConfiguration2.flags).to.eql(['NO_ATTESTER_SUBMIT', 'HIDE_ARMOR_META', 'DEFAULT_REMEMBER_PASS_PHRASE']); - expect(clientConfiguration2.custom_keyserver_url).to.equal('https://localhost:8001'); + expect(clientConfiguration2.custom_keyserver_url).to.equal(`https://localhost:${port}`); expect(clientConfiguration2.key_manager_url).to.be.an.undefined; expect(clientConfiguration2.allow_attester_search_only_for_domains).to.eql(['allowed_domain1.test', 'allowed_domain2.test']); expect(clientConfiguration2.disallow_attester_search_for_domains).to.be.an.undefined; @@ -1374,7 +1360,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T mockBackendData.clientConfigurationForDomain[domain] = { flags: ['NO_PRV_BACKUP', 'ENFORCE_ATTESTER_SUBMIT', 'PRV_AUTOIMPORT_OR_AUTOGEN', 'PASS_PHRASE_QUIET_AUTOGEN', 'DEFAULT_REMEMBER_PASS_PHRASE'], // custom_keyserver_url: undefined, - key_manager_url: 'https://localhost:8001/flowcrypt-email-key-manager', + key_manager_url: `https://localhost:${port}/flowcrypt-email-key-manager`, // allow_attester_search_only_for_domains: undefined, disallow_attester_search_for_domains: [], enforce_keygen_algo: 'rsa3072', @@ -1382,7 +1368,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T }; const extraAuthHeaders = { Authorization: `Bearer ${accessToken}` }; /* eslint-enable @typescript-eslint/naming-convention */ - let gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + let gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await Util.sleep(3); // read the local storage from via the extension's own page (settings) const { cryptup_settingssettingsflowcrypttest_rules: rules3 } = await settingsPage.getFromLocalStorage(['cryptup_settingssettingsflowcrypttest_rules']); @@ -1400,15 +1386,15 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T expect(clientConfiguration3.enforce_keygen_algo).to.equal('rsa3072'); expect(clientConfiguration3.enforce_keygen_expire_months).to.be.an.undefined; expect(clientConfiguration3.custom_keyserver_url).to.be.an.undefined; - expect(clientConfiguration3.key_manager_url).to.equal('https://localhost:8001/flowcrypt-email-key-manager'); + expect(clientConfiguration3.key_manager_url).to.equal(`https://localhost:${port}/flowcrypt-email-key-manager`); await gmailPage.close(); // configure an error mockBackendData.clientConfigurationForDomain[domain] = new HttpClientErr('Test error', Status.BAD_REQUEST); - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await PageRecipe.waitForToastToAppearAndDisappear( gmailPage, 'Failed to update FlowCrypt Client Configuration: ' + - 'BrowserMsg(ajax) Bad Request: 400 when GET-ing https://localhost:8001/shared-tenant-fes/api/v1/client-configuration?domain=settings.flowcrypt.test (no body)' + `BrowserMsg(ajax) Bad Request: 400 when GET-ing https://localhost:${port}/shared-tenant-fes/api/v1/client-configuration?domain=settings.flowcrypt.test (no body)` ); await gmailPage.close(); // check that the configuration hasn't changed @@ -1427,16 +1413,16 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T expect(clientConfiguration4.enforce_keygen_algo).to.equal('rsa3072'); expect(clientConfiguration4.enforce_keygen_expire_months).to.be.an.undefined; expect(clientConfiguration4.custom_keyserver_url).to.be.an.undefined; - expect(clientConfiguration4.key_manager_url).to.equal('https://localhost:8001/flowcrypt-email-key-manager'); + expect(clientConfiguration4.key_manager_url).to.equal(`https://localhost:${port}/flowcrypt-email-key-manager`); await settingsPage.close(); }) ); - ava.default( + test( 'settings - email change to account that has FORBID_STORING_PASS_PHRASE', testWithBrowser('ci.tests.gmail', async (t, browser) => { const acct1 = 'ci.tests.gmail@flowcrypt.test'; const acct2 = 'user@forbid-storing-passphrase-client-configuration.flowcrypt.test'; - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acct1)); + const settingsPage = await browser.newExtensionSettingsPage(t, acct1); const { cryptup_citestsgmailflowcrypttest_rules: oldRules, cryptup_citestsgmailflowcrypttest_passphrase_07481C8ACF9D49FE: savedPassphrase1 } = await settingsPage.getFromLocalStorage(['cryptup_citestsgmailflowcrypttest_rules', 'cryptup_citestsgmailflowcrypttest_passphrase_07481C8ACF9D49FE']); expect(savedPassphrase1).not.to.be.an('undefined'); @@ -1480,7 +1466,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await settingsPage.close(); }) ); - ava.default( + test( 'settings - adding a key honors FORBID_STORING_PASS_PHRASE ClientConfiguration', testWithBrowser(undefined, async (t, browser) => { const { acctEmail, settingsPage } = await BrowserRecipe.setUpFcForbidPpStoringAcct(t, browser); @@ -1508,11 +1494,11 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T expect(savedPassphrase2).to.be.an('undefined'); }) ); - ava.default( + test( "settings - password messages' expiry settings shouldn't be available for FES users", testWithBrowser('compatibility', async (t, browser) => { const acct1 = 'flowcrypt.compatibility@gmail.com'; - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings('flowcrypt.compatibility@gmail.com')); + const settingsPage = await browser.newExtensionSettingsPage(t, 'flowcrypt.compatibility@gmail.com'); const securitySettingsFrame1 = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-security-page', ['security.htm']); expect(await securitySettingsFrame1.isElementVisible('@container-password-messages-expiry')).to.equal(true); await SettingsPageRecipe.closeDialog(settingsPage); @@ -1530,7 +1516,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await settingsPage1.close(); }) ); - ava.default.todo('settings - change passphrase - mismatch curent pp'); - ava.default.todo('settings - change passphrase - mismatch new pp'); + test.todo('settings - change passphrase - mismatch curent pp'); + test.todo('settings - change passphrase - mismatch new pp'); } }; diff --git a/test/source/tests/setup.ts b/test/source/tests/setup.ts index ffd3ddde449..cd50fa220e3 100644 --- a/test/source/tests/setup.ts +++ b/test/source/tests/setup.ts @@ -1,6 +1,6 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ -import * as ava from 'ava'; +import test from 'ava'; import { Config, TestVariant, Util } from './../util'; import { SetupPageRecipe } from './page-recipe/setup-page-recipe'; @@ -16,14 +16,13 @@ import { Key, KeyInfoWithIdentity, KeyUtil } from '../core/crypto/key'; import { testConstants } from './tooling/consts'; import { InboxPageRecipe } from './page-recipe/inbox-page-recipe'; import { PageRecipe } from './page-recipe/abstract-page-recipe'; -import { TestUrls } from '../browser/test-urls'; import { BrowserHandle, ControllablePage } from '../browser'; import { OauthPageRecipe } from './page-recipe/oauth-page-recipe'; import { AvaContext } from './tooling'; import { opgp } from '../core/crypto/pgp/openpgpjs-custom'; const getAuthorizationHeader = async (t: AvaContext, browser: BrowserHandle, acctEmail: string) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acctEmail)); + const settingsPage = await browser.newExtensionSettingsPage(t, acctEmail); const accessToken = await BrowserRecipe.getGoogleAccessToken(settingsPage, acctEmail); await settingsPage.close(); // eslint-disable-next-line @typescript-eslint/naming-convention @@ -34,7 +33,7 @@ const openMockGmailPage = async (t: AvaContext, browser: BrowserHandle, acctEmai const authorizationHeader = hasPermission ? await getAuthorizationHeader(t, browser, acctEmail) : { Authorization: 'Bearer emulating-not-properly-set-up-extension' }; // eslint-disable-line @typescript-eslint/naming-convention - return await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, authorizationHeader); + return await browser.newMockGmailPage(t, authorizationHeader); }; export const defineSetupTests = (testVariant: TestVariant, testWithBrowser: TestWithBrowser) => { @@ -42,15 +41,15 @@ export const defineSetupTests = (testVariant: TestVariant, testWithBrowser: Test // note - `SetupPageRecipe.createKey` tests are in `defineFlakyTests` - running serially // because the keygen CPU spike can cause trouble to other concurrent tests - ava.default.todo('setup - no connection when pulling backup - retry prompt shows and works'); + test.todo('setup - no connection when pulling backup - retry prompt shows and works'); - ava.default.todo('setup - simple - no connection when making a backup - retry prompt shows'); + test.todo('setup - simple - no connection when making a backup - retry prompt shows'); - ava.default.todo('setup - advanced - no connection when making a backup - retry prompt shows'); + test.todo('setup - advanced - no connection when making a backup - retry prompt shows'); - ava.default.todo('setup - no connection when submitting public key - retry prompt shows and works'); + test.todo('setup - no connection when submitting public key - retry prompt shows and works'); - ava.default( + test( 'settings > login > close oauth window > close popup', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginButCloseOauthWindowBeforeGrantingPermission( @@ -62,17 +61,17 @@ export const defineSetupTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'setup - invalid csrf token returns error on gmail login', testWithBrowser(undefined, async (t, browser) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings()); + const settingsPage = await browser.newExtensionSettingsPage(t); const oauthPopup = await browser.newPageTriggeredBy(t, () => settingsPage.waitAndClick('@action-connect-to-gmail')); await OauthPageRecipe.mock(t, oauthPopup, 'test.invalid.csrf@gmail.com', 'login'); await settingsPage.waitAndRespondToModal('error', 'confirm', 'Wrong oauth CSRF token. Please try again.'); }) ); - ava.default( + test( 'setup - optional checkbox for each email aliases', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.compatibility@gmail.com'); @@ -94,7 +93,7 @@ export const defineSetupTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'setup - import key - do not submit - did not use before', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.imported@gmail.com'); @@ -107,7 +106,7 @@ export const defineSetupTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'setup - import unarmored key from file', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.imported@gmail.com'); @@ -122,7 +121,7 @@ export const defineSetupTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'setup - import invalid key file', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.imported@gmail.com'); @@ -137,7 +136,7 @@ export const defineSetupTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'setup - import key - submit - used before', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.used.pgp@gmail.com'); @@ -150,7 +149,7 @@ export const defineSetupTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'setup - import key - naked - choose my own pass phrase', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.import.naked@gmail.com'); @@ -163,7 +162,7 @@ export const defineSetupTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'setup - import key - naked - auto-generate a pass phrase', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.import.naked@gmail.com'); @@ -176,9 +175,9 @@ export const defineSetupTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default.todo('setup - import key - naked - do not supply pass phrase gets error'); + test.todo('setup - import key - naked - do not supply pass phrase gets error'); - ava.default( + test( 'setup - import key - fix key self signatures', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.imported@gmail.com'); @@ -191,7 +190,7 @@ export const defineSetupTests = (testVariant: TestVariant, testWithBrowser: Test }) ); - ava.default( + test( 'setup - import key - fix key self signatures - skip invalid uid', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.imported@gmail.com'); @@ -209,7 +208,7 @@ export const defineSetupTests = (testVariant: TestVariant, testWithBrowser: Test // // The test will also succeed if local openpgp.js is patched and // `!this.users.length` condition is removed from the Key constructor. - ava.default.failing( + test.failing( 'setup - import key - fix uids', testWithBrowser( undefined, @@ -221,7 +220,7 @@ export const defineSetupTests = (testVariant: TestVariant, testWithBrowser: Test ) ); - ava.default( + test( 'setup - import key - warning on primary has no secret', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.imported@gmail.com'); @@ -312,7 +311,7 @@ ZAvn6PBX7vsaReOVa2zsnuY5g70xCxvzHIwR94POu5cENwRtCkrppFnISALpQ1kA }) ); - ava.default( + test( 'setup - import key - two e-mails on the screen', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.imported@gmail.com'); @@ -407,7 +406,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - recover with a pass phrase - skip remaining', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.compatibility@gmail.com'); @@ -418,7 +417,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - recover with a pass phrase - 1pp1 then 2pp1', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.compatibility@gmail.com'); @@ -430,7 +429,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - recover with a pass phrase - 1pp2 then 2pp1', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.compatibility@gmail.com'); @@ -442,7 +441,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - recover with a pass phrase - 2pp1 then 1pp1', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.compatibility@gmail.com'); @@ -454,7 +453,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - recover with a pass phrase - 2pp1 then 1pp2', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.compatibility@gmail.com'); @@ -466,7 +465,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - recover with a pass phrase - 1pp1 then 1pp2 (shows already recovered), then 2pp1', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.compatibility@gmail.com'); @@ -479,7 +478,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'test re-auth after updating chrome extension', testWithBrowser('compatibility', async (t, browser) => { const acctEmail = 'flowcrypt.compatibility@gmail.com'; @@ -506,7 +505,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'mail.google.com - success notif after setup, click hides it, does not re-appear + offers to reauth', testWithBrowser('compatibility', async (t, browser) => { const acct = 'flowcrypt.compatibility@gmail.com'; @@ -517,7 +516,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== await gmailPage.notPresent(['@webmail-notification-setup', '@notification-setup-action-close', '@notification-successfully-setup-action-close']); // below test that can re-auth after lost access (simulating situation when user changed password on google) await Util.wipeGoogleTokensUsingExperimentalSettingsPage(t, browser, acct); - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acct)); + const settingsPage = await browser.newExtensionSettingsPage(t, acct); await settingsPage.waitAndRespondToModal('confirm', 'cancel', 'FlowCrypt must be re-connected to your Google account.'); // *** these tests below are very flaky in CI environment, Google will want to re-authenticate the user for whatever reason // // opening secure compose should trigger an api call which causes a reconnect notification @@ -539,7 +538,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'mail.google.com - setup prompt notif + hides when close clicked + reappears + setup link opens settings', testWithBrowser(undefined, async (t, browser) => { const acct = 'flowcrypt.compatibility@gmail.com'; @@ -563,7 +562,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'mail.google.com - setup prompt notification shows up + dismiss hides it + does not reappear if dismissed', testWithBrowser(undefined, async (t, browser) => { const acct = 'flowcrypt.compatibility@gmail.com'; @@ -585,11 +584,11 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - test adding missing self-signature key issue', testWithBrowser('compatibility', async (t, browser) => { const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acctEmail)); + const settingsPage = await browser.newExtensionSettingsPage(t, acctEmail); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const addKeyPopup = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-add-key-page', ['add_key.htm']); await addKeyPopup.waitAndClick('@source-paste'); @@ -617,7 +616,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup [not using key manager] - notify users when their keys expire soon', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.notify.expiring.keys@gmail.com'; @@ -675,7 +674,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup [using key manager] - notify users when their keys expire soon', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.notify.expiring.keys.updating.key@key-manager-autogen.flowcrypt.test'; @@ -726,15 +725,15 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default.todo('setup - recover with a pass phrase - 1pp1 then wrong, then skip'); - // ava.default('setup - recover with a pass phrase - 1pp1 then wrong, then skip', test_with_browser(async (t, browser) => { + test.todo('setup - recover with a pass phrase - 1pp1 then wrong, then skip'); + // test('setup - recover with a pass phrase - 1pp1 then wrong, then skip', test_with_browser(async (t, browser) => { // const settingsPage = await BrowserRecipe.open_settings_login_approve(t, browser,'flowcrypt.compatibility@gmail.com'); // await SetupPageRecipe.setup_recover(settingsPage, 'flowcrypt.compatibility.1pp1', {has_recover_more: true, click_recover_more: true}); // await SetupPageRecipe.setup_recover(settingsPage, 'flowcrypt.wrong.passphrase', {wrong_passphrase: true}); // await Util.sleep(200); // })); - ava.default( + test( 'setup - recover with a pass phrase - no remaining', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.recovered@gmail.com'); @@ -742,7 +741,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - fail to recover with a wrong pass phrase', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.recovered@gmail.com'); @@ -753,7 +752,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - fail to recover with a wrong pass phrase at first, then recover with good pass phrase', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.recovered@gmail.com'); @@ -762,7 +761,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - import key - submit - offline - retry', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.used.pgp@gmail.com'); @@ -775,17 +774,17 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - enterprise users should be redirected to their help desk when an error occured', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'flowcrypt.compatibility@gmail.com'; if (testVariant === 'ENTERPRISE-MOCK') { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings()); + const settingsPage = await browser.newExtensionSettingsPage(t); const oauthPopup = await browser.newPageTriggeredBy(t, () => settingsPage.waitAndClick('@action-connect-to-gmail')); await OauthPageRecipe.mock(t, oauthPopup, acctEmail, 'login_with_invalid_state'); await settingsPage.waitForContent('@container-error-modal-text', 'please contact your Help Desk'); } else if (testVariant === 'CONSUMER-MOCK') { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings()); + const settingsPage = await browser.newExtensionSettingsPage(t); const oauthPopup = await browser.newPageTriggeredBy(t, () => settingsPage.waitAndClick('@action-connect-to-gmail')); await OauthPageRecipe.mock(t, oauthPopup, acctEmail, 'login_with_invalid_state'); await settingsPage.waitForContent('@container-error-modal-text', 'write us at human@flowcrypt.com'); @@ -793,7 +792,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'has.pub@client-configuration-test.flowcrypt.test - no backup, no keygen', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'has.pub@client-configuration-test.flowcrypt.test'); @@ -820,7 +819,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'invalid.pub@client-configuration-test.flowcrypt.test - no backup, no keygen', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'invalid.pub@client-configuration-test.flowcrypt.test'); @@ -840,7 +839,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'no.pub@client-configurations-test - no backup, no keygen, enforce attester submit with submit err', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'no.pub@client-configuration-test.flowcrypt.test'); @@ -860,7 +859,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'user@no-submit-client-configuration.flowcrypt.test - do not submit to attester', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'user@no-submit-client-configuration.flowcrypt.test'); @@ -877,7 +876,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - manualEnter honors DEFAULT_REMEMBER_PASS_PHRASE ClientConfiguration', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'user@default-remember-passphrase-client-configuration.flowcrypt.test'; @@ -904,7 +903,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'user@no-search-domains-client-configuration.flowcrypt.test - do not search attester for recipients on particular domains', testWithBrowser(undefined, async (t, browser) => { // disallowed searching attester for pubkeys on "flowcrypt.com" domain @@ -924,7 +923,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'user@only-allow-some-domains-client-configuration.flowcrypt.test - search attester for recipients only on particular domains', testWithBrowser(undefined, async (t, browser) => { // disallow_attester_search_for_domains is not respected if allow_attester_search_only_for_domains is set @@ -944,7 +943,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( "user@no-allow-domains-client-configuration.flowcrypt.test - search attester for recipients doesn't work on any domains", testWithBrowser(undefined, async (t, browser) => { // as `allow_attester_search_only_for_domains: []` is set, attester search shouldn't work for any domains @@ -958,7 +957,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'user@no-search-wildcard-domains-client-configuration.flowcrypt.test - do not search attester for recipients on any domain', testWithBrowser(undefined, async (t, browser) => { // disallowed searching attester for pubkeys on * domain @@ -973,7 +972,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'get.key@key-manager-autogen.flowcrypt.test - automatic setup with key found on key manager', testWithBrowser(undefined, async (t, browser) => { const acct = 'get.key@key-manager-autogen.flowcrypt.test'; @@ -1022,7 +1021,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== ); }; - ava.default( + test( 'get.updating.key@key-manager-choose-passphrase-forbid-storing.flowcrypt.test - automatic update of key found on key manager', testWithBrowser(undefined, async (t, browser) => { const acct = 'get.updating.key@key-manager-choose-passphrase-forbid-storing.flowcrypt.test'; @@ -1040,7 +1039,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }; const set1 = await retrieveAndCheckKeys(settingsPage, acct, 1); // 1. EKM returns the same key, no update, no toast - let gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + let gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await PageRecipe.noToastAppears(gmailPage); await gmailPage.notPresent('@dialog-passphrase'); const set2 = await retrieveAndCheckKeys(settingsPage, acct, 1); @@ -1049,14 +1048,14 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== // 2. EKM returns a newer version of the existing key const someOlderVersion = await updateAndArmorKey(set2[0]); MOCK_KM_KEYS[acct].response = { privateKeys: [{ decryptedPrivateKey: someOlderVersion }] }; - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await PageRecipe.waitForToastToAppearAndDisappear(gmailPage, 'Account keys updated'); const set3 = await retrieveAndCheckKeys(settingsPage, acct, 1); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - expect(set3[0].lastModified!).to.be.greaterThan(set2[0].lastModified!); // an update happened + expect(set3[0].lastModified).to.be.greaterThan(set2[0].lastModified!); // an update happened await gmailPage.close(); // 3. EKM returns the same version of the existing key, no toast, no update - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await PageRecipe.noToastAppears(gmailPage); await gmailPage.notPresent('@dialog-passphrase'); const set4 = await retrieveAndCheckKeys(settingsPage, acct, 1); @@ -1064,7 +1063,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== // 4. Forget the passphrase, EKM the same version of the existing key, no prompt await InboxPageRecipe.finishSessionOnInboxPage(gmailPage); await gmailPage.close(); - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await PageRecipe.noToastAppears(gmailPage); await gmailPage.notPresent('@dialog-passphrase'); const set5 = await retrieveAndCheckKeys(settingsPage, acct, 1, passphrase); @@ -1072,7 +1071,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== await gmailPage.close(); // 5. EKM returns a newer version of the existing key, canceling passphrase prompt, no update MOCK_KM_KEYS[acct].response = { privateKeys: [{ decryptedPrivateKey: await updateAndArmorKey(set5[0]) }] }; - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await gmailPage.waitAll('@dialog-passphrase'); await ComposePageRecipe.cancelPassphraseDialog(gmailPage, 'keyboard'); await PageRecipe.noToastAppears(gmailPage); @@ -1080,7 +1079,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== expect(set6[0].lastModified).to.equal(set5[0].lastModified); // no update await gmailPage.close(); // 6. EKM returns a newer version of the existing key, entering the passphrase, update toast - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await gmailPage.waitAll('@dialog-passphrase'); { const passphraseDialog = await gmailPage.getFrame(['passphrase.htm']); @@ -1096,7 +1095,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== await gmailPage.close(); // 7. EKM returns an older version of the existing key, no toast, no update MOCK_KM_KEYS[acct].response = { privateKeys: [{ decryptedPrivateKey: someOlderVersion }] }; - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await PageRecipe.noToastAppears(gmailPage); await gmailPage.notPresent('@dialog-passphrase'); const set8 = await retrieveAndCheckKeys(settingsPage, acct, 1); @@ -1106,7 +1105,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== MOCK_KM_KEYS[acct].response = { privateKeys: [{ decryptedPrivateKey: someOlderVersion }, { decryptedPrivateKey: testConstants.existingPrv }], }; - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await PageRecipe.waitForToastToAppearAndDisappear(gmailPage, 'Account keys updated'); await gmailPage.notPresent('@dialog-passphrase'); const set9 = await retrieveAndCheckKeys(settingsPage, acct, 2); @@ -1118,7 +1117,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== await gmailPage.close(); // 9. EKM returns a newer version of one key, fully omitting the other one, a toast, an update and removal MOCK_KM_KEYS[acct].response = { privateKeys: [{ decryptedPrivateKey: await updateAndArmorKey(mainKey9[0]) }] }; - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await PageRecipe.waitForToastToAppearAndDisappear(gmailPage, 'Account keys updated'); await gmailPage.notPresent('@dialog-passphrase'); const set10 = await retrieveAndCheckKeys(settingsPage, acct, 1); @@ -1131,7 +1130,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== await InboxPageRecipe.finishSessionOnInboxPage(gmailPage); await gmailPage.close(); MOCK_KM_KEYS[acct].response = { privateKeys: [{ decryptedPrivateKey: testConstants.unprotectedPrvKey }] }; - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await gmailPage.waitAll('@dialog-passphrase'); { const passphraseDialog = await gmailPage.getFrame(['passphrase.htm']); @@ -1147,7 +1146,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== expect(set11.map(entry => entry.id)).to.eql(['392FB1E9FF4184659AB6A246835C0141B9ECF536']); await gmailPage.close(); // 11. EKM returns a new third key, we enter a passphrase matching an existing key, update happens, the old key is removed - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await gmailPage.waitAll('@dialog-passphrase'); { const passphraseDialog = await gmailPage.getFrame(['passphrase.htm']); @@ -1172,7 +1171,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== decryptedPrivateKey: testConstants.unprotectedPrvKey.substring(0, testConstants.unprotectedPrvKey.length / 2), }, ]; - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await PageRecipe.waitForToastToAppearAndDisappear( gmailPage, 'Could not update keys from EKM due to error: BrowserMsg(processAndStoreKeysFromEkmLocally) sendRawResponse::Error: Some keys could not be parsed' @@ -1186,7 +1185,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== await gmailPage.close(); // 13. EKM down, no toast, no passphrase dialog, no updates MOCK_KM_KEYS[acct] = { badRequestError: 'RequestTimeout' }; - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await PageRecipe.noToastAppears(gmailPage); await gmailPage.notPresent('@dialog-passphrase'); const set14 = await retrieveAndCheckKeys(settingsPage, acct, 1, passphrase); @@ -1201,7 +1200,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'put.updating.key@key-manager-choose-passphrase-forbid-storing.flowcrypt.test - updates of key found on key manager via setup page (with passphrase)', testWithBrowser(undefined, async (t, browser) => { const acct = 'put.updating.key@key-manager-choose-passphrase-forbid-storing.flowcrypt.test'; @@ -1217,7 +1216,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== const set1 = await retrieveAndCheckKeys(settingsPage, acct, 1); // 1. EKM returns the empty set, forcing to auto-generate MOCK_KM_KEYS[acct].response = { privateKeys: [] }; - let gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + let gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); // The new settingsPage is loaded in place of the existing settings tab (this is by design) // However, after a second the newly-activated (old) settings tab loses focus in favour of the gmailPage, why is that? // Looks like Puppeteer's misbehaviour @@ -1236,7 +1235,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== // 2. Adding a new key from the key manager when there is none in the storage // First, erase the keys by supplying an empty set from mock EKM MOCK_KM_KEYS[acct].response = { privateKeys: [] }; - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await PageRecipe.noToastAppears(gmailPage); await gmailPage.notPresent('@dialog-passphrase'); await gmailPage.close(); @@ -1246,7 +1245,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== // Secondly, configure mock EKM to return a key and re-load the gmail page MOCK_KM_KEYS[acct] = { response: { privateKeys: [{ decryptedPrivateKey: testConstants.updatingPrv }] } }; gmailPage = await browser.newPage(t, undefined, undefined, extraAuthHeaders); - const newSettingsPage = await browser.newPageTriggeredBy(t, () => gmailPage.goto(TestUrls.mockGmailUrl())); + const newSettingsPage = await browser.newPageTriggeredBy(t, () => gmailPage.goto(t.urls?.mockGmailUrl() ?? '')); await SetupPageRecipe.autoSetupWithEKM(newSettingsPage, { enterPp: { passphrase, checks: { isSavePassphraseChecked: false, isSavePassphraseHidden: true } }, }); @@ -1258,7 +1257,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'get.updating.key@key-manager-autoimport-no-prv-create.flowcrypt.test - updates of key found on key manager when NO_PRV_CREATE', testWithBrowser(undefined, async (t, browser) => { const acct = 'get.updating.key@key-manager-autoimport-no-prv-create.flowcrypt.test'; @@ -1271,7 +1270,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== const set1 = await retrieveAndCheckKeys(settingsPage, acct, 1); MOCK_KM_KEYS[acct].response = { privateKeys: [] }; // 1. EKM returns the empty set, auto-generation is not allowed, hence the error modal - let gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + let gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await gmailPage.waitAndRespondToModal('error', 'confirm', 'Keys for your account were not set up yet - please ask your systems administrator'); await PageRecipe.noToastAppears(gmailPage); await gmailPage.close(); @@ -1280,17 +1279,17 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== await settingsPage.close(); // 2. Adding a new key from the key manager when there is none in the storage MOCK_KM_KEYS[acct] = { response: { privateKeys: [{ decryptedPrivateKey: testConstants.updatingPrv }] } }; - gmailPage = await browser.newPage(t, TestUrls.mockGmailUrl(), undefined, extraAuthHeaders); + gmailPage = await browser.newMockGmailPage(t, extraAuthHeaders); await PageRecipe.waitForToastToAppearAndDisappear(gmailPage, 'Account keys updated'); await gmailPage.close(); - const dbPage = await browser.newPage(t, TestUrls.extension('chrome/dev/ci_unit_test.htm')); + const dbPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); const set2 = await retrieveAndCheckKeys(dbPage, acct, 1); expect(set2[0].id).to.equal(set1[0].id); // the key was received from the EKM await dbPage.close(); }) ); - ava.default( + test( 'user@custom-sks.flowcrypt.test - Respect custom key server url', testWithBrowser(undefined, async (t, browser) => { const acct = 'user@custom-sks.flowcrypt.test'; @@ -1302,14 +1301,14 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== await composePage.close(); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const contactsFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-contacts-page', ['contacts.htm', 'placement=settings']); - await contactsFrame.waitForContent('@custom-key-server-description', 'using custom SKS pubkeyserver: https://localhost:8001'); + await contactsFrame.waitForContent('@custom-key-server-description', `using custom SKS pubkeyserver: https://localhost:${t.urls?.port}`); }) ); - ava.default.todo('DEFAULT_REMEMBER_PASS_PHRASE with auto-generation when all keys are removed by EKM'); + test.todo('DEFAULT_REMEMBER_PASS_PHRASE with auto-generation when all keys are removed by EKM'); // should we re-use the known passphrase or delete it from the storage in this scenario? - ava.default( + test( 'user@no-flags-client-configuration.flowcrypt.test - should show error when no flags is present', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'user@no-flags-client-configuration.flowcrypt.test'; @@ -1319,7 +1318,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'null-setting@null-client-configuration.flowcrypt.test - should not show error when no setting is present', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'null-setting@null-client-configuration.flowcrypt.test'; @@ -1329,7 +1328,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'get.key@key-manager-choose-passphrase.flowcrypt.test - passphrase chosen by user with key found on key manager', testWithBrowser(undefined, async (t, browser) => { const acct = 'get.key@key-manager-choose-passphrase.flowcrypt.test'; @@ -1354,7 +1353,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'get.key@key-manager-choose-passphrase-forbid-storing.flowcrypt.test - passphrase chosen by user with key found on key manager and forbid storing', testWithBrowser(undefined, async (t, browser) => { const acct = 'get.key@key-manager-choose-passphrase-forbid-storing.flowcrypt.test'; @@ -1381,7 +1380,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'user@passphrase-session-length-client-configuration.flowcrypt.test - passphrase should expire in in_memory_pass_phrase_session_length', testWithBrowser(undefined, async (t, browser) => { const acctEmail = 'user@passphrase-session-length-client-configuration.flowcrypt.test'; @@ -1413,7 +1412,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'get.key@key-manager-autoimport-no-prv-create.flowcrypt.test - respect NO_PRV_CREATE when key not found on key manager', testWithBrowser(undefined, async (t, browser) => { const acct = 'get.key@key-manager-autoimport-no-prv-create.flowcrypt.test'; @@ -1422,7 +1421,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'get.key@no-submit-client-configuration.key-manager-autogen.flowcrypt.test - automatic setup with key found on key manager and no submit rule', testWithBrowser(undefined, async (t, browser) => { const acct = 'get.key@no-submit-client-configuration.key-manager-autogen.flowcrypt.test'; @@ -1440,7 +1439,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'put.key@key-manager-autogen.flowcrypt.test - automatic setup with key not found on key manager, then generated', testWithBrowser(undefined, async (t, browser) => { const acct = 'put.key@key-manager-autogen.flowcrypt.test'; @@ -1468,7 +1467,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'get.error@key-manager-autogen.flowcrypt.test - handles error during KM key GET', testWithBrowser(undefined, async (t, browser) => { const acct = 'get.error@key-manager-autogen.flowcrypt.test'; @@ -1476,13 +1475,13 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== await SetupPageRecipe.autoSetupWithEKM(settingsPage, { expectErrView: { title: 'Server responded with an unexpected error.', - text: '500 when GET-ing https://localhost:8001/flowcrypt-email-key-manager/v1/keys/private (no body): -> Intentional error for get.error to test client behavior', + text: `500 when GET-ing https://localhost:${t.urls?.port}/flowcrypt-email-key-manager/v1/keys/private (no body): -> Intentional error for get.error to test client behavior`, }, }); }) ); - ava.default( + test( 'put.error@key-manager-autogen.flowcrypt.test - handles error during KM key PUT', testWithBrowser(undefined, async (t, browser) => { const acct = 'put.error@key-manager-autogen.flowcrypt.test'; @@ -1495,14 +1494,14 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== await Util.sleep(0.5); const details = await settingsPage.read('@container-overlay-details'); expect(details).to.contain( - '500 when PUT-ing https://localhost:8001/flowcrypt-email-key-manager/v1/keys/private string: privateKey -> Intentional error for put.error user to test client behavior' + `500 when PUT-ing https://localhost:${t.urls?.port}/flowcrypt-email-key-manager/v1/keys/private string: privateKey -> Intentional error for put.error user to test client behavior` ); expect(details).to.not.contain('PRIVATE KEY'); expect(details).to.not.contain(' { const acct = 'fail@key-manager-server-offline.flowcrypt.test'; @@ -1516,7 +1515,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'get.key@ekm-offline-retrieve.flowcrypt.test - show clear error to user - during retrieval', testWithBrowser(undefined, async (t, browser) => { const acct = 'get.key@ekm-offline-retrieve.flowcrypt.test'; @@ -1529,7 +1528,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'expire@key-manager-keygen-expiration.flowcrypt.test - ClientConfiguration enforce_keygen_expire_months: 1', testWithBrowser(undefined, async (t, browser) => { const acct = 'expire@key-manager-keygen-expiration.flowcrypt.test'; @@ -1549,7 +1548,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'reject.client.keypair@key-manager-autogen.flowcrypt.test - does not leak sensitive info on err 400, shows informative err', testWithBrowser(undefined, async (t, browser) => { const acct = 'reject.client.keypair@key-manager-autogen.flowcrypt.test'; @@ -1566,17 +1565,18 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== await Util.sleep(0.5); const details = await settingsPage.read('@container-overlay-details'); expect(details).to.contain( - '405 when PUT-ing https://localhost:8001/flowcrypt-email-key-manager/v1/keys/private string: ' + + `405 when PUT-ing https://localhost:${t.urls?.port}/flowcrypt-email-key-manager/v1/keys/private string: ` + 'privateKey -> No key has been generated for reject.client.keypair@key-manager-autogen.flowcrypt.test yet' ); expect(details).to.not.contain('PRIVATE KEY'); }) ); - ava.default( + test( 'user@standardsubdomainfes.localhost:8001 - uses FES on standard domain', testWithBrowser(undefined, async (t, browser) => { - const acct = 'user@standardsubdomainfes.localhost:8001'; // added port to trick extension into calling the mock + const port = t.urls?.port; + const acct = `user@standardsubdomainfes.localhost:${port}`; // added port to trick extension into calling the mock const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, acct); await SetupPageRecipe.manualEnter( settingsPage, @@ -1585,7 +1585,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== { isSavePassphraseChecked: false, isSavePassphraseHidden: false } ); const debugFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-show-local-store-contents', ['debug_api.htm']); - await debugFrame.waitForContent('@container-pre', 'fes.standardsubdomainfes.localhost:8001'); // FES url on standard subdomain + await debugFrame.waitForContent('@container-pre', `fes.standardsubdomainfes.localhost:${port}`); // FES url on standard subdomain await debugFrame.waitForContent('@container-pre', 'got.this@fromstandardfes.com'); // org rules from FES }) ); @@ -1594,7 +1594,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== * enterprise - expects FES to be set up. when it's not, show nice error * consumer - tolerates the missing FES and and sets up without it */ - ava.default( + test( 'no.fes@example.com - skip FES on consumer, show friendly message on enterprise', testWithBrowser(undefined, async (t, browser) => { const acct = 'no.fes@example.com'; @@ -1621,7 +1621,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - s/mime private key', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'flowcrypt.test.key.imported@gmail.com'); @@ -1637,7 +1637,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== } if (testVariant === 'CONSUMER-MOCK') { - ava.default( + test( 'setup - imported key with multiple alias should show checkbox per alias', testWithBrowser(undefined, async (t, browser) => { expect((await KeyUtil.parse(testConstants.keyMultiAliasedUser)).emails.length).to.equals(3); @@ -1664,7 +1664,7 @@ AN8G3r5Htj8olot+jm9mIa5XLXWzMNUZgg== }) ); - ava.default( + test( 'setup - imported key from a file with multiple alias', testWithBrowser(undefined, async (t, browser) => { const settingsPage = await BrowserRecipe.openSettingsLoginApprove(t, browser, 'multi.aliased.user@example.com'); diff --git a/test/source/tests/tooling/browser-recipe.ts b/test/source/tests/tooling/browser-recipe.ts index 9f688bdd845..7eeb784c9bf 100644 --- a/test/source/tests/tooling/browser-recipe.ts +++ b/test/source/tests/tooling/browser-recipe.ts @@ -18,7 +18,7 @@ export class BrowserRecipe { public static oldAndNewComposeButtonSelectors = ['div.z0[class*="_destroyable"]', '.new_secure_compose_window_button']; public static openSettingsLoginButCloseOauthWindowBeforeGrantingPermission = async (t: AvaContext, browser: BrowserHandle, acctEmail: string) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings()); + const settingsPage = await browser.newExtensionSettingsPage(t); const oauthPopup = await browser.newPageTriggeredBy(t, () => settingsPage.waitAndClick('@action-connect-to-gmail')); await OauthPageRecipe.google(t, oauthPopup, acctEmail, 'close'); await settingsPage.waitAndRespondToModal('info', 'confirm', 'Explaining FlowCrypt webmail permissions'); @@ -26,7 +26,7 @@ export class BrowserRecipe { }; public static openSettingsLoginApprove = async (t: AvaContext, browser: BrowserHandle, acctEmail: string) => { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acctEmail)); + const settingsPage = await browser.newExtensionSettingsPage(t, acctEmail); const oauthPopup = await browser.newPageTriggeredBy(t, () => settingsPage.waitAndClick('@action-connect-to-gmail')); await OauthPageRecipe.google(t, oauthPopup, acctEmail, 'approve'); return settingsPage; @@ -125,14 +125,12 @@ export class BrowserRecipe { // eslint-disable-next-line @typescript-eslint/naming-convention const list = await gmail.users.drafts.list({ userId: 'me', access_token: accessToken }); if (list.data.drafts) { - /* eslint-disable @typescript-eslint/no-non-null-assertion */ await Promise.all( - list.data - .drafts!.filter(draft => draft.id) - // eslint-disable-next-line @typescript-eslint/naming-convention + list.data.drafts + .filter(draft => draft.id) + // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-non-null-assertion .map(draft => gmail.users.drafts.delete({ id: draft.id!, userId: 'me', access_token: accessToken })) ); - /* eslint-enable @typescript-eslint/no-non-null-assertion */ } }; diff --git a/test/source/tests/tooling/index.ts b/test/source/tests/tooling/index.ts index 72c6ed87458..dae9c25a0b6 100644 --- a/test/source/tests/tooling/index.ts +++ b/test/source/tests/tooling/index.ts @@ -1,14 +1,17 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ -import * as ava from 'ava'; +import { ExecutionContext } from 'ava'; +import { TestUrls } from '../../browser/test-urls'; import { Consts } from '../../test'; -export type AvaContext = ava.ExecutionContext & { +export type AvaContext = ExecutionContext & { retry?: true; attemptNumber?: number; totalAttempts?: number; attemptText?: string; + extensionDir?: string; + urls?: TestUrls; }; const MAX_ATT_SIZE = 5 * 1024 * 1024; diff --git a/test/source/tests/unit-browser.ts b/test/source/tests/unit-browser.ts index 42b74611be1..a7eec17ef78 100644 --- a/test/source/tests/unit-browser.ts +++ b/test/source/tests/unit-browser.ts @@ -1,10 +1,9 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ -import * as ava from 'ava'; +import test from 'ava'; import { TestVariant } from '../util'; import { CommonAcct, TestWithBrowser } from '../test'; -import { TestUrls } from '../browser/test-urls'; import { readdirSync, readFileSync } from 'fs'; import { Buf } from '../core/buf'; import { testConstants } from './tooling/consts'; @@ -17,10 +16,10 @@ export const defineUnitBrowserTests = (testVariant: TestVariant, testWithBrowser const defineAvaTest = (title: string, testCode: string, acct?: CommonAcct, flag?: 'only') => { // eslint-disable-next-line no-only-tests/no-only-tests - (flag !== 'only' ? ava.default : ava.default.only)( + (flag !== 'only' ? test : test.only)( title, testWithBrowser(acct, async (t, browser) => { - const hostPage = await browser.newPage(t, TestUrls.extension(`chrome/dev/ci_unit_test.htm`)); + const hostPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); // update host page h1 await hostPage.target.evaluate(title => { window.document.getElementsByTagName('h1')[0].textContent = title; @@ -31,10 +30,11 @@ export const defineUnitBrowserTests = (testVariant: TestVariant, testWithBrowser (window as any).testConstants = object; }, testConstants); // prepare code to run + const testCodeWithMockPort = testCode.replace(/\:8001/g, ':' + t.urls?.port); const runThisCodeInBrowser = ` (async () => { try { - return await ${testCode} + return await ${testCodeWithMockPort} } catch (e) { return "unit test threw something:" + String(e) + "\\n\\n" + e.stack; } @@ -55,16 +55,15 @@ export const defineUnitBrowserTests = (testVariant: TestVariant, testWithBrowser .toUtfStr() .trim(); const testCasesInFile = unitTestCodes.split('\nBROWSER_UNIT_TEST_NAME('); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const header = testCasesInFile.shift()!; - if (!header.startsWith('/* ©️ 2016')) { + const header = testCasesInFile.shift(); + if (!header?.startsWith('/* ©️ 2016')) { throw Error(`Expecting ${browserUnitTestsFolder}/${filename} to start with '/* ©️ 2016'`); } if (header.includes('require(') || header.includes('import')) { // do not import anything. Add deps to ci_unit_test.ts throw Error(`Unexpected import statement found in ${browserUnitTestsFolder}/${filename}`); } - const unitTests = []; + const unitTests: UnitTest[] = []; for (let code of testCasesInFile) { if (code.includes('/*')) { // just to make sure we don't parse something wrongly. Block comment only allowed in header. @@ -131,7 +130,7 @@ export const defineUnitBrowserTests = (testVariant: TestVariant, testWithBrowser allUnitTests.push(...parseTestFile(filename)); } } - const markedAsOnly: UnitTest[] = allUnitTests.filter(unitTest => unitTest.only); + const markedAsOnly = allUnitTests.filter(unitTest => unitTest.only); if (!markedAsOnly.length) { // no tests marked as only - run all for (const unitTest of allUnitTests) { @@ -143,7 +142,7 @@ export const defineUnitBrowserTests = (testVariant: TestVariant, testWithBrowser defineAvaTest(unitTest.title, unitTest.code, unitTest.acct, 'only'); } // eslint-disable-next-line no-only-tests/no-only-tests - ava.default.only('reminder to remove .only', async t => { + test.only('reminder to remove .only', async t => { t.fail(`some tests marked as .only, preventing other tests from running`); }); } diff --git a/test/source/tests/unit-node.ts b/test/source/tests/unit-node.ts index 369570e4009..36a6648b093 100644 --- a/test/source/tests/unit-node.ts +++ b/test/source/tests/unit-node.ts @@ -1,6 +1,6 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ -import * as ava from 'ava'; +import test from 'ava'; import { MsgBlock } from '../core/msg-block'; import { MsgBlockParser } from '../core/msg-block-parser'; @@ -40,7 +40,7 @@ export const equals = (a: string | Uint8Array, b: string | Uint8Array) => { export const defineUnitNodeTests = (testVariant: TestVariant) => { if (testVariant !== 'CONSUMER-LIVE-GMAIL') { - ava.default(`[unit][KeyUtil.parse] throw if parse methods expecting exactly one key find more than one`, async t => { + test(`[unit][KeyUtil.parse] throw if parse methods expecting exactly one key find more than one`, async t => { const unarmoredKeys = Buffer.from([ ...(await PgpArmor.dearmor(testConstants.flowcryptcompatibilityPublicKey7FDE685548AEA788)).data, ...(await PgpArmor.dearmor(testConstants.pubkey2864E326A5BE488A)).data, @@ -58,7 +58,7 @@ export const defineUnitNodeTests = (testVariant: TestVariant) => { t.pass(); }); - ava.default(`[unit][MsgBlockParser.detectBlocks] does not get tripped on blocks with unknown headers`, async t => { + test(`[unit][MsgBlockParser.detectBlocks] does not get tripped on blocks with unknown headers`, async t => { expect( MsgBlockParser.detectBlocks("This text breaks email and Gmail web app.\n\n-----BEGIN FOO-----\n\nEven though it's not a vaild PGP m\n\nMuhahah") ).to.deep.equal({ @@ -73,7 +73,7 @@ export const defineUnitNodeTests = (testVariant: TestVariant) => { t.pass(); }); - ava.default(`[unit][MsgBlockParser.detectBlocks] ignores false-positive blocks`, async t => { + test(`[unit][MsgBlockParser.detectBlocks] ignores false-positive blocks`, async t => { const input = `Hello, sending you the promised json: { "entries" : [ { @@ -94,7 +94,7 @@ export const defineUnitNodeTests = (testVariant: TestVariant) => { t.pass(); }); - ava.default(`[unit][MsgBlockParser.detectBlocks] replaces intended blocks`, async t => { + test(`[unit][MsgBlockParser.detectBlocks] replaces intended blocks`, async t => { const prv = `-----BEGIN PGP PRIVATE KEY BLOCK-----\r\nVersion: FlowCrypt 7.6.9 Gmail Encryption\r\nComment: Seamlessly send and receive encrypted email\r\n\r\n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\r\n+P9DgunMb5OtkDwm6WWxpzV150LJcA==\r\n=FAco\r\n-----END PGP PRIVATE KEY BLOCK-----`; const pub = `-----BEGIN PGP PUBLIC KEY BLOCK-----\r\nVersion: FlowCrypt 7.6.9 Gmail Encryption\r\nComment: Seamlessly send and receive encrypted email\r\n\r\nxsBNBF5mRKEBCADX62s0p6mI6yrxB/ui/LqxfG4RcQzZJf8ah52Ynu1n8V7Y\r\n7143LmT3MfCDw1bfHu2k1OK7hT+BOi6sXas1D/fVtjz5WwuoBvwf1DBZ7eq8\r\ntMQbLqQ7m/A8uwrVFOhWfuxulM7RuzIPIgv4HqtKKEugprUd80bPus45+f80\r\nH6ZSgEpmZD6t9JShY6f8pU1OHcnPqFsFF0sLyOk7WcCG5Li3WjkwU/lIu18q\r\nR26oLb5UM8z6vv6JD29GmqCj+OLYaPk8b00kdpGEvTjw3VzGM+tXOgUf2y1T\r\nK9UfhMNkyswxUZw543CMTdw9V0+AzM0q70T/p0fP9nlJCv6M3bQm6D/vABEB\r\nAAHNL0VrbSBVc2VyIDxla21AZWttLW9yZy1ydWxlcy10ZXN0LmZsb3djcnlw\r\ndC5jb20+wsB1BBABCAAfBQJeZkShBgsJBwgDAgQVCAoCAxYCAQIZAQIbAwIe\r\nAQAKCRDESadeBea4P0KvCACD5uOgGxwGEmUWfH8EXPK7npDKulmoZnSWYrfC\r\nX3ctUKXjwPBWRXYid7LChnQAR6SRcyxyD1Eoel5ZVrJyKHqRkxcanFHeqRU1\r\nOyOgtsQyPIGtLipmOgc6i5JYhqbQ4mNu10CGS6ZKhjf6rFIqLl/8f4lnBc28\r\nUqVuP20Ru6KJZTVVQRF28FweMByR/3LyAWfObMwXJ0+uFEV941VEDv5MGdId\r\nfePTP2cHRSJxPqVhpPWtfzYLStUzLFvtLfE45hympok4lZeKfLVtZVVQEgT+\r\nojEImdiZQJ0dT+jeJhmuTjzURQcLapXv2GLBUZaY2zfoAXR31QNYjADOxlrO\r\nutSUzsBNBF5mRKEBCACVNQTzI2Cf1+G3q38OtXO89tuBI/a5TjcHh/sFIJB6\r\nPPuEg/uW+EsjkgI3yk+UZZd6iYohO2mJcJ7MnaFHOu7tmOEaaHSiYsA0RTnV\r\nqUBlbHbsl2oSlQJ/mjJ4cWq5ateuLHhx2RV0t1bm2anHJnqKGkqYqXA72m5g\r\nrLzRSJ9M43wQRheGWGNoNdg4kPxU+PjYwfk2ARX5SCUKoG0qp0RhRMplX74u\r\nYi+Ek/9qSyZevmhK55sXIUNwLsuEhejlr0iucOt2vcIybQ9EbMXz62yYMRjY\r\ngy4SxW5aQJxXFeWkSo6wzMqQ1ZiSArRCezBk+mftxNrmwmtCcJajQt2uAQQV\r\nABEBAAHCwF8EGAEIAAkFAl5mRKECGwwACgkQxEmnXgXmuD/7VAf+IMJMoADc\r\ndWNhn45AvkwbzSmYt4i2aRGe+qojswwYzvFBFZtyZ/FKV2+LHfKUBI18FRmH\r\nmKEba1UUetflytxiAwZxSJSf7Yz/NDiWaVn0eOLopmFMiPb02a5i3CjbLsDe\r\nex2y/69R0+fQc+rE3HZ04C8H/YAqFV0VOv3L+2EztOGK7KOZOx4toR05oDqb\r\nZbiDzwhsa2MugHLPLZuGl3eGk+n/EcINhopHg+HU8MHQE6rADvrok6QiYVhp\r\nGqi8ksD3kBAk43hGRSD2m/WDPWa/h2sh5rVswTKUDtv1fd1H6Ff5FnK21LHj\r\nEk0f+P9DgunMb5OtkDwm6WWxpzV150LJcA==\r\n=Hcoc\r\n-----END PGP PUBLIC KEY BLOCK-----`; const input = `Hello, these should get replaced:\n${prv}\n\nAnd this one too:\n\n${pub}`; @@ -108,7 +108,7 @@ export const defineUnitNodeTests = (testVariant: TestVariant) => { t.pass(); }); - ava.default(`[unit][PgpKey.usableForEncryptionButExpired] recognizes usable expired key`, async t => { + test(`[unit][PgpKey.usableForEncryptionButExpired] recognizes usable expired key`, async t => { const armored = '-----BEGIN PGP PRIVATE KEY BLOCK-----\nVersion: FlowCrypt 7.0.1 Gmail Encryption\nComment: Seamlessly send and receive encrypted email\n\n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\n+gib+vSxHvLhC6oDBA==\n=RIPF\n-----END PGP PRIVATE KEY BLOCK-----'; const expiredKey = await KeyUtil.parse(armored); @@ -116,7 +116,7 @@ export const defineUnitNodeTests = (testVariant: TestVariant) => { t.pass(); }); - ava.default('[unit][KeyUtil.parse] S/MIME key parsing works', async t => { + test('[unit][KeyUtil.parse] S/MIME key parsing works', async t => { /* // generate a key pair const keys = forge.pki.rsa.generateKeyPair(2048); @@ -221,7 +221,7 @@ Nu6RzBFp27492OM1t0vvbEsNkMgD3/wSCMev5rleor1bvTT+GkSEArEdpHRydtcN WeNYP84Yjw6OFSHdi2W0VojRGhxm7PZCMqswN/XaBg== -----END CERTIFICATE-----`; - ava.default('[unit][KeyUtil.parse] S/MIME key parsing of HTTPS cert', async t => { + test('[unit][KeyUtil.parse] S/MIME key parsing of HTTPS cert', async t => { // parsing throws because the domain name doesn't look like an e-mail // address await t.throwsAsync(() => KeyUtil.parse(httpsCert), { @@ -230,7 +230,7 @@ WeNYP84Yjw6OFSHdi2W0VojRGhxm7PZCMqswN/XaBg== }); }); - ava.default('[unit][KeyUtil.parse] Unknown key family parsing fails', async t => { + test('[unit][KeyUtil.parse] Unknown key family parsing fails', async t => { await t.throwsAsync(() => KeyUtil.parse('dummy string for unknown key'), { instanceOf: Error, message: 'Key type is unknown, expecting OpenPGP or x509 S/MIME', @@ -297,7 +297,7 @@ sOLAw7KgpiL2+0v777saxSO5vtufJCKk4OOEaVDufeijlejKTM+H7twVer4iGqiW =wYbc -----END PGP PRIVATE KEY BLOCK-----`; - ava.default('[unit][KeyUtil.parse] OpenPGP parsing of expired key', async t => { + test('[unit][KeyUtil.parse] OpenPGP parsing of expired key', async t => { const key = await KeyUtil.parse(expiredPgp); expect(key.id).to.equal('3449178FCAAF758E24CB68BE62CB4E6F9ECA6FA1'); expect(key.allIds.length).to.equal(2); @@ -369,7 +369,7 @@ cmKFmmDYm+rrWuAv6Q== =oWPu -----END PGP PRIVATE KEY BLOCK-----`; - ava.default('[unit][KeyUtil.parse] OpenPGP parsing of not-expired key', async t => { + test('[unit][KeyUtil.parse] OpenPGP parsing of not-expired key', async t => { const key = await KeyUtil.parse(notExpiredPgp); expect(key.id).to.equal('7C3B38BB2C8A7E693C29DF455C08033166AF91E3'); expect(key.allIds.length).to.equal(2); @@ -404,7 +404,7 @@ McqZHXuttXHc2wZ2nvjjtbzWSEzxvpAA/jdWwCNBg65Wh93Df5/6Ec05W8AgFwJH =E46c -----END PGP PUBLIC KEY BLOCK-----`; - ava.default('[unit][KeyUtil.parse] OpenPGP parsing of never expiring key', async t => { + test('[unit][KeyUtil.parse] OpenPGP parsing of never expiring key', async t => { const key = await KeyUtil.parse(nonExpiringKey); expect(key.id).to.equal('8DD737C086DAB3313EB76D5F4A92152DF2FD6DBD'); expect(key.expiration).to.equal(undefined); @@ -468,7 +468,7 @@ zZFGf6poIjKUC8V2Zww6 =Hjpw -----END PGP PUBLIC KEY BLOCK-----`; - ava.default('[unit][KeyUtil.readMany] Parsing two OpenPGP armored together keys', async t => { + test('[unit][KeyUtil.readMany] Parsing two OpenPGP armored together keys', async t => { const { keys, errs } = await KeyUtil.readMany(Buf.fromUtfStr(pgpArmoredTwoKeys)); expect(keys.length).to.equal(2); expect(errs.length).to.equal(0); @@ -539,7 +539,7 @@ vpQiyk4ceuTNkUZ/qmgiMpQLxXZnDDo= =lQQh -----END PGP PUBLIC KEY BLOCK-----`; - ava.default('[unit][KeyUtil.readMany] Parsing two OpenPGP armored separate keys', async t => { + test('[unit][KeyUtil.readMany] Parsing two OpenPGP armored separate keys', async t => { const { keys, errs } = await KeyUtil.readMany(Buf.fromUtfStr(pgpArmoredSeparate)); expect(keys.length).to.equal(2); expect(errs.length).to.equal(0); @@ -549,7 +549,7 @@ vpQiyk4ceuTNkUZ/qmgiMpQLxXZnDDo= t.pass(); }); - ava.default('[unit][KeyUtil.readMany] Parsing one S/MIME key', async t => { + test('[unit][KeyUtil.readMany] Parsing one S/MIME key', async t => { const { keys, errs } = await KeyUtil.readMany(Buf.fromUtfStr(testConstants.smimeCert)); expect(keys.length).to.equal(1); expect(errs.length).to.equal(0); @@ -558,7 +558,7 @@ vpQiyk4ceuTNkUZ/qmgiMpQLxXZnDDo= t.pass(); }); - ava.default('[unit][KeyUtil.parse] S/MIME key parsing of unprotected PKCS#8 private key and mismatching certificate', async t => { + test('[unit][KeyUtil.parse] S/MIME key parsing of unprotected PKCS#8 private key and mismatching certificate', async t => { await t.throwsAsync( () => KeyUtil.parse(`${testConstants.smimeUnencryptedKey} @@ -568,7 +568,7 @@ ${testConstants.smimeCert}`), t.pass(); }); - ava.default('[unit][KeyUtil.decrypt] S/MIME key decryption of mismatching private key', async t => { + test('[unit][KeyUtil.decrypt] S/MIME key decryption of mismatching private key', async t => { const encryptedKey = await KeyUtil.parse(`${testConstants.smimeEncryptedKey} ${testConstants.smimeCert}`); await t.throwsAsync(() => KeyUtil.decrypt(encryptedKey, 'AHbxhwquX5pc'), { @@ -578,7 +578,7 @@ ${testConstants.smimeCert}`); t.pass(); }); - ava.default(`[unit][KeyUtil.decrypt] throws on incorrect PKCS#8 encrypted private key`, async t => { + test(`[unit][KeyUtil.decrypt] throws on incorrect PKCS#8 encrypted private key`, async t => { const encryptedKey = await KeyUtil.parse(`-----BEGIN ENCRYPTED PRIVATE KEY----- AAAAAAAAAAAAAAAAzzzzzzzzzzzzzzzzzzzzzzzzzzzz..... @@ -591,7 +591,7 @@ ${testConstants.smimeCert}`); t.pass(); }); - ava.default(`[unit][KeyUtil.parse] throws on incorrect PKCS#8 private key`, async t => { + test(`[unit][KeyUtil.parse] throws on incorrect PKCS#8 private key`, async t => { await t.throwsAsync( () => KeyUtil.parse(`-----BEGIN PRIVATE KEY----- @@ -604,7 +604,7 @@ ${testConstants.smimeCert}`), t.pass(); }); - ava.default(`[unit][KeyUtil.parse] throws on incorrect RSA PKCS#8 private key`, async t => { + test(`[unit][KeyUtil.parse] throws on incorrect RSA PKCS#8 private key`, async t => { await t.throwsAsync( () => KeyUtil.parse(`-----BEGIN RSA PRIVATE KEY----- @@ -617,7 +617,7 @@ ${testConstants.smimeCert}`), t.pass(); }); - ava.default('[unit][KeyUtil.armor] S/MIME key from PKCS#12 is armored to PKCS#8', async t => { + test('[unit][KeyUtil.armor] S/MIME key from PKCS#12 is armored to PKCS#8', async t => { const p12 = readFileSync('test/samples/smime/human-pwd-original-PKCS12.pfx', 'binary'); const key = SmimeKey.parseDecryptBinary(Buf.fromRawBytesStr(p12), 'AHbxhwquX5pc'); expect(key.id).to.equal('9B5FCFF576A032495AFE77805354351B39AB3BC6'); @@ -641,7 +641,7 @@ ${testConstants.smimeCert}`), t.pass(); }); - ava.default('[unit][KeyUtil.readMany] Parsing unarmored S/MIME certificate', async t => { + test('[unit][KeyUtil.readMany] Parsing unarmored S/MIME certificate', async t => { const pem = forge.pem.decode(testConstants.smimeCert)[0]; const { keys, errs } = await KeyUtil.readMany(Buf.fromRawBytesStr(pem.body)); expect(keys.length).to.equal(1); @@ -651,7 +651,7 @@ ${testConstants.smimeCert}`), t.pass(); }); - ava.default('[unit][KeyUtil.parse] issuerAndSerialNumber of S/MIME certificate is constructed according to PKCS#7', async t => { + test('[unit][KeyUtil.parse] issuerAndSerialNumber of S/MIME certificate is constructed according to PKCS#7', async t => { const key = await KeyUtil.parse(testConstants.smimeCert); const buf = Buf.with( ( @@ -667,7 +667,7 @@ ${testConstants.smimeCert}`), t.pass(); }); - ava.default('[unit][MsgUtil.encryptMessage] duplicate S/MIME recipients are collapsed into one', async t => { + test('[unit][MsgUtil.encryptMessage] duplicate S/MIME recipients are collapsed into one', async t => { const key = await KeyUtil.parse(testConstants.smimeCert); const buf = Buf.with( ( @@ -687,7 +687,7 @@ ${testConstants.smimeCert}`), t.pass(); }); - ava.default('[unit][KeyUtil.parse] Correctly extracting email from SubjectAltName of S/MIME certificate', async t => { + test('[unit][KeyUtil.parse] Correctly extracting email from SubjectAltName of S/MIME certificate', async t => { /* // generate a key pair const keys = forge.pki.rsa.generateKeyPair(2048); @@ -775,7 +775,7 @@ jLwe8W9IMt765T5x5oux9MmPDXF05xHfm4qfH/BMO3a802x5u2gJjJjuknrFdgXY const smimeAndPgp = testConstants.smimeCert + '\r\n' + expiredPgp; - ava.default('[unit][KeyUtil.readMany] Parsing one S/MIME and one OpenPGP armored keys', async t => { + test('[unit][KeyUtil.readMany] Parsing one S/MIME and one OpenPGP armored keys', async t => { const { keys, errs } = await KeyUtil.readMany(Buf.fromUtfStr(smimeAndPgp)); expect(keys.length).to.equal(2); expect(errs.length).to.equal(0); @@ -786,7 +786,7 @@ jLwe8W9IMt765T5x5oux9MmPDXF05xHfm4qfH/BMO3a802x5u2gJjJjuknrFdgXY t.pass(); }); - ava.default('[unit][KeyUtil.parse] key was never usable', async t => { + test('[unit][KeyUtil.parse] key was never usable', async t => { const expiredPubKey = '-----BEGIN PGP PUBLIC KEY BLOCK-----\r\nVersion: FlowCrypt Email Encryption 7.8.4\r\nComment: Seamlessly send and receive encrypted email\r\n\r\nxsBNBF8QF1cBCADFQRM0S6kJ1LxL+Y2hqz+w2PIbAKnNpV4gr1D0jEX9ygMY\r\nYxyjGP7QcK2umeBrioWBUET/5yu+KkSVFOxGwXw2m1MqJXZH6fPumgDBEAYg\r\n8afLXI/5Rh7Lp2Z3eBDog6W0I9EOHAB6iFHQgc5m+PUlehMZ23VUKxDpb4kW\r\nsIts1b8Zm0sSimUf15bz0nGxCf00bYf5lCuxBfgAQGK+FgpIAdc03a7VI4zJ\r\nc/A18PR4mlMeDfIj2yWKaL4ka8lr8d+qAP2Cu0I6GcNgBUl5yCWc/6S20J52\r\nKjoa48w1vdAYzK1hjTE7INLrB6WKOCPLoY0jRuqE+ksarw6JtNsAhNrFABEB\r\nAAHNKTxoYXMub2xkZXIua2V5Lm9uLmF0dGVzdGVyQHJlY2lwaWVudC5jb20+\r\nwsCTBBABCAAmBQJfEBpQBQkAAAACBgsJBwgDAgQVCAoCBBYCAQACGQECGwMC\r\nHgEAIQkQ0CoIfv1WLLMWIQQoKZEjISHFGWNfjmPQKgh+/VYss4EFB/9apXb/\r\nRYrf/FwK3NEeAuVAjq4sQFOC+e2sOO1Y1i74Hm5Q3YpL5FPWxg1zzQR3cKlw\r\ngwGiTBH9Re86KuB6XIIhropA94c0c5RGXf4Syb66hsp+xyb5laoazW274M26\r\nLhNou77CFgJ4UTOYPqNoDADcGPCoYzlU/tkp8q+vuIEBuizNkO+vOdFdrG9x\r\nON2n7aPVBWTHTy7PXVQr6wYfbj2c3cmH9ju5bZKoKoZ7niR3jQi+NUAHf09Z\r\nkwWGoYwD37iTtPWrn/nnMqp7nqJxpChsJvtfousgKHWUA1IsCXoSeExZuXYU\r\nVpJduSYQx5H6dy4QwmK8bzRfra/l5O6sRTbNzsBNBF8QF1cBCADL0rwgqVw3\r\nsQ6JD7j9eOkbcc0iNrxLqYWnBCu71opLWVQ0b8mw9DqT3WuXtvOVmEBkqDig\r\nq9Q78BbD2EfQhFNuvcE5GL38BvyUkpgZBC+vi9UrisQTStmLS5bSsT7aipwM\r\nGy3tXFIoHX8XQk8swbKa20fCYd5KKZr3wFBZ6mtXN3O1qgelZ4HEl/bCFz6c\r\nuvZUFLvLaMksXh7um2/bjnB6E9uktn/ts34rbYIuHxVTLs6bq4VbPiUilurz\r\n8uzAsU2HMw2QTQTaJzycJyYzdDxAIXrSmtFah2/wqSYC82r65sA17y3gtbHq\r\neP0pzbzbMQitPCV2poxIHJuiMYh4iWV9ABEBAAHCwHwEGAEIAA8FAl8QGlAF\r\nCQAAAAICGwwAIQkQ0CoIfv1WLLMWIQQoKZEjISHFGWNfjmPQKgh+/VYsswOo\r\nCAC2gkz5f7RLboxFxgbjleY/SWttf9j5pJGCfcaPzLGo8wCbnEUdhs+FqAml\r\nGDF1yZAexCQLBukVhil1yEnknaX1emeHB7d4g6cQFoKtSHeVZ0C9mmM+OJMn\r\nZoGVylTsOLMmVXM/CXyp9JUAlo/oZm1Zpb9RK5rvNJukH1f0DajQjWlC09Y9\r\nVLVDBxlJccsEdas1yojMDHMqNOMiNaAlA33mrY3ucAiKb4q3uP9IuDRuD83M\r\ncoDahY5p8xl6IbKQhnxoWtBgGJWrlwBZro83z9HzW4LmP99pPZqfLZQAevUL\r\n+oQiPqyh512p6O5usc1GkEoN9cn9b/qnvnRu5RMxC/vI\r\n=NveA\r\n-----END PGP PUBLIC KEY BLOCK-----\r\n'; const parsed = await KeyUtil.parse(expiredPubKey); @@ -797,7 +797,7 @@ jLwe8W9IMt765T5x5oux9MmPDXF05xHfm4qfH/BMO3a802x5u2gJjJjuknrFdgXY }); /* eslint-disable @typescript-eslint/no-non-null-assertion */ - ava.default('[unit][MsgUtil.decryptMessage] finds correct key to verify signature', async t => { + test('[unit][MsgUtil.decryptMessage] finds correct key to verify signature', async t => { const data = await GoogleData.withInitializedData('ci.tests.gmail@flowcrypt.test'); const msg: GmailMsg = data.getMessage('1766644f13510f58')!; const enc = Buf.fromBase64Str(msg!.raw!) @@ -852,7 +852,7 @@ jLwe8W9IMt765T5x5oux9MmPDXF05xHfm4qfH/BMO3a802x5u2gJjJjuknrFdgXY t.pass(); }); - ava.default('[unit][MsgUtil.verifyDetached] verifies Thunderbird html signed message', async t => { + test('[unit][MsgUtil.verifyDetached] verifies Thunderbird html signed message', async t => { const data = await GoogleData.withInitializedData('flowcrypt.compatibility@gmail.com'); const msg: GmailMsg = data.getMessage('17daefa0eb077da6')!; const msgText = Buf.fromBase64Str(msg!.raw!).toUtfStr(); @@ -876,7 +876,7 @@ jLwe8W9IMt765T5x5oux9MmPDXF05xHfm4qfH/BMO3a802x5u2gJjJjuknrFdgXY t.pass(); }); - ava.default('[unit][MsgUtil.verifyDetached] verifies Thunderbird text signed message', async t => { + test('[unit][MsgUtil.verifyDetached] verifies Thunderbird text signed message', async t => { const data = await GoogleData.withInitializedData('flowcrypt.compatibility@gmail.com'); const msg: GmailMsg = data.getMessage('17dad75e63e47f97')!; const msgText = Buf.fromBase64Str(msg!.raw!).toUtfStr(); @@ -900,7 +900,7 @@ jLwe8W9IMt765T5x5oux9MmPDXF05xHfm4qfH/BMO3a802x5u2gJjJjuknrFdgXY t.pass(); }); - ava.default('[unit][MsgUtil.verifyDetached] verifies Firefox rich text signed message', async t => { + test('[unit][MsgUtil.verifyDetached] verifies Firefox rich text signed message', async t => { const data = await GoogleData.withInitializedData('flowcrypt.compatibility@gmail.com'); const msg: GmailMsg = data.getMessage('175ccd8755eab85f')!; const msgText = Buf.fromBase64Str(msg!.raw!).toUtfStr(); @@ -920,7 +920,7 @@ jLwe8W9IMt765T5x5oux9MmPDXF05xHfm4qfH/BMO3a802x5u2gJjJjuknrFdgXY t.pass(); }); - ava.default(`[unit][MsgUtil.verifyDetached] returns non-fatal error when signature doesn't match`, async t => { + test(`[unit][MsgUtil.verifyDetached] returns non-fatal error when signature doesn't match`, async t => { const sigText = Buf.fromUtfStr(`-----BEGIN PGP SIGNATURE----- wsB5BAABCAAjFiEEK7IZd28jzkjruGCcID+ucHYAU4EFAmG1nzIFAwAAAAAACgkQID+ucHYAU4H1 @@ -960,7 +960,7 @@ jSB6A93JmnQGIkAem/kzGkKclmfAdGfc4FS+3Cn+6Q==Xmrz }); /* eslint-enable @typescript-eslint/no-non-null-assertion */ - ava.default('[unit][MsgUtil.getSortedKeys,matchingKeyids] must be able to find matching keys', async t => { + test('[unit][MsgUtil.getSortedKeys,matchingKeyids] must be able to find matching keys', async t => { const passphrase = 'some pass for testing'; const key1 = await OpenPGPKey.create([{ name: 'Key1', email: 'key1@test.com' }], 'curve25519', passphrase, 0); const key2 = await OpenPGPKey.create([{ name: 'Key2', email: 'key2@test.com' }], 'curve25519', passphrase, 0); @@ -1005,7 +1005,7 @@ jSB6A93JmnQGIkAem/kzGkKclmfAdGfc4FS+3Cn+6Q==Xmrz t.pass(); }); - ava.default('[unit][OpenPGPKey.create] multiple uids', async t => { + test('[unit][OpenPGPKey.create] multiple uids', async t => { const passphrase = 'some pass for testing'; const key = await OpenPGPKey.create( [ @@ -1024,7 +1024,7 @@ jSB6A93JmnQGIkAem/kzGkKclmfAdGfc4FS+3Cn+6Q==Xmrz t.pass(); }); - ava.default('[OpenPGPKey.fingerprintToLongid] only works for pgp', async t => { + test('[OpenPGPKey.fingerprintToLongid] only works for pgp', async t => { // shorten pgp fingerprint to become longid expect(OpenPGPKey.fingerprintToLongid('3449178FCAAF758E24CB68BE62CB4E6F9ECA6FA1')).to.equal('62CB4E6F9ECA6FA1'); // throw on s/mime id @@ -1036,7 +1036,7 @@ jSB6A93JmnQGIkAem/kzGkKclmfAdGfc4FS+3Cn+6Q==Xmrz t.pass(); }); - ava.default('[Attachment.sanitizeName] for special and unicode characters', async t => { + test('[Attachment.sanitizeName] for special and unicode characters', async t => { // slash expect(Attachment.sanitizeName('abc/def')).to.equal('abc_def'); // backslash @@ -1070,7 +1070,7 @@ jSB6A93JmnQGIkAem/kzGkKclmfAdGfc4FS+3Cn+6Q==Xmrz // created: 2020-10-15 expires: never usage: E const prvEncryptForSubkeyOnly = `-----BEGIN PGP PRIVATE KEY BLOCK-----\n\n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\n1b0dyVac7jV1Tgs=\n=4Jfy\n-----END PGP PRIVATE KEY BLOCK-----\n`; - ava.default('[MsgUtil.encryptMessage] do not decrypt message when encrypted for key not meant for encryption', async t => { + test('[MsgUtil.encryptMessage] do not decrypt message when encrypted for key not meant for encryption', async t => { const data = Buf.fromUtfStr('hello'); const passphrase = 'pass phrase'; const tmpPrv = await KeyUtil.parse(prvEncryptForSubkeyOnly); @@ -1107,7 +1107,7 @@ jSB6A93JmnQGIkAem/kzGkKclmfAdGfc4FS+3Cn+6Q==Xmrz t.pass(); }); - ava.default('[KeyUtil.diagnose] displays PK and SK usage', async t => { + test('[KeyUtil.diagnose] displays PK and SK usage', async t => { const usageRegex = /\[\-\] \[(.*)\]/; /* eslint-disable @typescript-eslint/no-non-null-assertion */ const result1 = await KeyUtil.diagnose(await KeyUtil.parse(pubEncryptForPrimaryIsFine), ''); @@ -1272,7 +1272,7 @@ ZAvn6PBX7vsaReOVa2zsnuY5g70xCxvzHIwR94POu5cENwRtCkrppFnISALpQ1kA =/3Ew -----END PGP PRIVATE KEY BLOCK-----`; - ava.default('[KeyUtil.diagnose] handles incorrect passphrase', async t => { + test('[KeyUtil.diagnose] handles incorrect passphrase', async t => { const result = await KeyUtil.diagnose(await KeyUtil.parse(rsaPrimaryKeyAndSubkeyBothHavePrivateKey), '4321'); expect(result.get('Is Private?')).to.equal('[-] true'); expect(result.get('User id 0')).to.equal('Test1 (rsa) '); @@ -1311,7 +1311,7 @@ ZAvn6PBX7vsaReOVa2zsnuY5g70xCxvzHIwR94POu5cENwRtCkrppFnISALpQ1kA t.pass(); }); - ava.default('[KeyUtil.diagnose] decrypts and successfully tests PK sign and SK encrypt', async t => { + test('[KeyUtil.diagnose] decrypts and successfully tests PK sign and SK encrypt', async t => { const result = await KeyUtil.diagnose(await KeyUtil.parse(rsaPrimaryKeyAndSubkeyBothHavePrivateKey), '1234'); expect(result.get('Is Private?')).to.equal('[-] true'); expect(result.get('User id 0')).to.equal('Test1 (rsa) '); @@ -1619,7 +1619,7 @@ jA== =lAqt -----END PGP PRIVATE KEY BLOCK-----`; - ava.default('[KeyUtil.diagnose] decrypts and tests PK missing private key and SK with private key', async t => { + test('[KeyUtil.diagnose] decrypts and tests PK missing private key and SK with private key', async t => { const result = await KeyUtil.diagnose(await KeyUtil.parse(rsaPrimaryKeyIsMissingPrivateKey), '1234'); expect(result.get('Is Private?')).to.equal('[-] true'); expect(result.get('User id 0')).to.equal('Test1 (rsa) '); @@ -1658,7 +1658,7 @@ jA== t.pass(); }); - ava.default('[KeyUtil.diagnose] decrypts and tests secure PK and insecure SK', async t => { + test('[KeyUtil.diagnose] decrypts and tests secure PK and insecure SK', async t => { const result = await KeyUtil.diagnose(await KeyUtil.parse(testConstants.rsa1024subkeyOnly), ''); expect(result.get('Is Private?')).to.equal('[-] true'); expect(result.get('User id 0')).to.equal('rsa1024subkey@test'); @@ -1697,7 +1697,7 @@ jA== t.pass(); }); - ava.default('[unit][KeyUtil.parse] correctly handles signing/encryption detection for PKSK with private keys', async t => { + test('[unit][KeyUtil.parse] correctly handles signing/encryption detection for PKSK with private keys', async t => { // testing encrypted key const encryptedKey = await KeyUtil.parse(rsaPrimaryKeyAndSubkeyBothHavePrivateKey); expect(encryptedKey.usableForSigning).to.be.true; @@ -1715,7 +1715,7 @@ jA== t.pass(); }); - ava.default('[unit][KeyUtil.decrypt] validates the private key', async t => { + test('[unit][KeyUtil.decrypt] validates the private key', async t => { const corruptedRsaKey = await KeyUtil.parse(`-----BEGIN PGP PRIVATE KEY BLOCK----- Comment: Corrupted encrypted RSA private key Comment: Passphrase is 123 @@ -1850,7 +1850,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz =//ru -----END PGP PRIVATE KEY BLOCK-----`; - ava.default('[unit][KeyUtil.parse] validates the private key if it is not encrypted', async t => { + test('[unit][KeyUtil.parse] validates the private key if it is not encrypted', async t => { await t.throwsAsync(() => KeyUtil.parse(unencryptedCorruptedRsaKey), { instanceOf: Error, message: 'Key is invalid', @@ -1858,7 +1858,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz t.pass(); }); - ava.default('[unit][KeyUtil.readBinary] validates the private key if it is not encrypted', async t => { + test('[unit][KeyUtil.readBinary] validates the private key if it is not encrypted', async t => { const binaryKey = (await PgpArmor.dearmor(unencryptedCorruptedRsaKey)).data; const { keys, err } = await KeyUtil.readBinary(binaryKey); expect(keys.length).to.equal(0); @@ -1867,7 +1867,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz t.pass(); }); - ava.default('[unit][KeyUtil.decrypt] correctly handles signing/encryption detection for PKSK with private keys', async t => { + test('[unit][KeyUtil.decrypt] correctly handles signing/encryption detection for PKSK with private keys', async t => { const dsakey = await KeyUtil.parse(dsaPrimaryKeyAndSubkeyBothHavePrivateKey); expect(await KeyUtil.decrypt(dsakey, '1234')).to.be.true; expect(dsakey.usableForSigning).to.be.true; @@ -1883,7 +1883,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz t.pass(); }); - ava.default('[unit][KeyUtil.parse] determines PK missing private key for signing', async t => { + test('[unit][KeyUtil.parse] determines PK missing private key for signing', async t => { // testing encrypted key const encryptedKey = await KeyUtil.parse(rsaPrimaryKeyIsMissingPrivateKey); expect(encryptedKey.usableForSigning).to.be.true; @@ -1901,7 +1901,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz t.pass(); }); - ava.default('[unit][KeyUtil.decrypt] determines PK missing private key for signing', async t => { + test('[unit][KeyUtil.decrypt] determines PK missing private key for signing', async t => { const dsakey = await KeyUtil.parse(dsaPrimaryKeyIsMissingPrivateKey); expect(await KeyUtil.decrypt(dsakey, '1234')).to.be.true; expect(dsakey.usableForSigning).to.be.true; @@ -1917,7 +1917,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz t.pass(); }); - ava.default('[unit][KeyUtil.parse] determines missing private key for encryption in expired key', async t => { + test('[unit][KeyUtil.parse] determines missing private key for encryption in expired key', async t => { const dsakey = await KeyUtil.parse(dsaExpiredPubkeysOnly); expect(dsakey.usableForEncryptionButExpired).to.be.true; expect(dsakey.usableForSigningButExpired).to.be.true; @@ -1935,7 +1935,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz t.pass(); }); - ava.default('[unit][KeyUtil.decrypt] handles PK missing private key for signing in expired key', async t => { + test('[unit][KeyUtil.decrypt] handles PK missing private key for signing in expired key', async t => { const dsakey = await KeyUtil.parse(dsaExpiredPrimaryKeyIsMissingPrivateKey); expect(await KeyUtil.decrypt(dsakey, '1234')).to.be.true; expect(dsakey.usableForEncryptionButExpired).to.be.true; @@ -1955,7 +1955,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz t.pass(); }); - ava.default('[unit][KeyUtil.parseBinary] handles OpenPGP binary key', async t => { + test('[unit][KeyUtil.parseBinary] handles OpenPGP binary key', async t => { const key = Buffer.from( 'mDMEX7JGnBYJKwYBBAHaRw8BAQdA8L8ZDEHJ3N8fojA1P0n9Tc2E0BTCl6AXq/b2ZoS5Evy0BlRl' + 'c3QgMYiQBBMWCAA4FiEExOEH3ZJIrCG1lTnB5pbLkt3W1hMFAl+yRpwCGwMFCwkIBwIGFQoJCAsC' + @@ -1969,7 +1969,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz t.pass(); }); - ava.default('[unit][KeyUtil.parseBinary] handles PKCS#12 binary key', async t => { + test('[unit][KeyUtil.parseBinary] handles PKCS#12 binary key', async t => { const key = Buffer.from( `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`, 'base64' @@ -1985,7 +1985,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz t.pass(); }); - ava.default('[unit][KeyUtil.parse] handles encrypted PKCS#8 key', async t => { + test('[unit][KeyUtil.parse] handles encrypted PKCS#8 key', async t => { const p8 = readFileSync('test/samples/smime/human-pwd-pem.txt', 'utf8'); let parsed = await KeyUtil.parse(p8); expect(parsed.id).to.equal('9B5FCFF576A032495AFE77805354351B39AB3BC6'); @@ -2017,7 +2017,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz t.pass(); }); - ava.default('[unit][KeyUtil.parse] correctly handles shuffled certificates in PEM', async t => { + test('[unit][KeyUtil.parse] correctly handles shuffled certificates in PEM', async t => { const p8 = readFileSync('test/samples/smime/human-pwd-shuffled-pem.txt', 'utf8'); let parsed = await KeyUtil.parse(p8); expect(parsed.id).to.equal('9B5FCFF576A032495AFE77805354351B39AB3BC6'); @@ -2049,7 +2049,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz t.pass(); }); - ava.default('[unit][KeyUtil.encrypt] encrypts S/MIME key', async t => { + test('[unit][KeyUtil.encrypt] encrypts S/MIME key', async t => { const p8 = readFileSync('test/samples/smime/human-unprotected-pem.txt', 'utf8'); let parsed = await KeyUtil.parse(p8); expect(parsed.id).to.equal('9B5FCFF576A032495AFE77805354351B39AB3BC6'); @@ -2078,7 +2078,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz t.pass(); }); - ava.default('[unit][SmimeKey.decryptMessage] decrypts an armored S/MIME PKCS#7 message', async t => { + test('[unit][SmimeKey.decryptMessage] decrypts an armored S/MIME PKCS#7 message', async t => { const p8 = readFileSync('test/samples/smime/human-unprotected-pem.txt', 'utf8'); const privateSmimeKey = await KeyUtil.parse(p8); const publicSmimeKey = await KeyUtil.asPublicKey(privateSmimeKey); @@ -2102,7 +2102,7 @@ PBcqDCjq5jgMhU1oyVclRK7jJdmu0Azvwo2lleLAFLdCzHEXWXUz t.pass(); }); - ava.default(`[unit][KeyUtil.parse] orders primary uids first`, async t => { + test(`[unit][KeyUtil.parse] orders primary uids first`, async t => { const armoredPrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- lQdGBGGJzUMBEADqrtfx3gxm50P6nqFt4j8kPmHuD7maxk/BE3X1SeEu/TBPtnsQ @@ -2304,7 +2304,7 @@ oYO0H2wzxUfJQIcXL8HfNs70eXJwD7U9F6gnIeUKA8+1NsQMgQE= t.pass(); }); - ava.default(`[unit][OpenPGPKey.parse] sets usableForEncryption and usableForSigning to false for RSA key less than 2048`, async t => { + test(`[unit][OpenPGPKey.parse] sets usableForEncryption and usableForSigning to false for RSA key less than 2048`, async t => { const rsa1024secret = `-----BEGIN PGP PRIVATE KEY BLOCK----- xcEYBGAID1EBBACypl5K0IoqFjfpSrIhbhT5H5MjQg4MKRlgMfqXjo8pEeB6Yf88wvBni36iRdSn @@ -2363,7 +2363,7 @@ kBXo t.pass(); }); - ava.default(`[unit][OpenPGPKey.parse] sets usableForEncryption to false and usableForSigning to true for 2048/RSA PK and 1024/RSA SK`, async t => { + test(`[unit][OpenPGPKey.parse] sets usableForEncryption to false and usableForSigning to true for 2048/RSA PK and 1024/RSA SK`, async t => { const key = await KeyUtil.parse(testConstants.rsa1024subkeyOnly); expect(key.usableForEncryption).to.equal(false); expect(key.usableForSigning).to.equal(true); @@ -2372,7 +2372,7 @@ kBXo t.pass(); }); - ava.default(`[unit][OpenPGPKey.decrypt] sets usableForEncryption to false and usableForSigning to true for 2048/RSA PK and 1024/RSA SK`, async t => { + test(`[unit][OpenPGPKey.decrypt] sets usableForEncryption to false and usableForSigning to true for 2048/RSA PK and 1024/RSA SK`, async t => { const key = await KeyUtil.parse(testConstants.rsa1024subkeyOnlyEncrypted); expect(key.usableForEncryption).to.equal(false); expect(key.usableForSigning).to.equal(true); @@ -2386,7 +2386,7 @@ kBXo t.pass(); }); - ava.default(`[unit][PgpArmor.dearmor] throws on incorrect sequence`, async t => { + test(`[unit][PgpArmor.dearmor] throws on incorrect sequence`, async t => { await expect( PgpArmor.dearmor(`-----BEGIN PGP MESSAGE----- @@ -2395,7 +2395,7 @@ AAAAAAAAAAAAAAAAzzzzzzzzzzzzzzzzzzzzzzzzzzzz.....`) t.pass(); }); - ava.default(`[unit][PgpArmor.dearmor] correctly handles long string`, async t => { + test(`[unit][PgpArmor.dearmor] correctly handles long string`, async t => { const source = Buffer.from('The test string concatenated many times to produce large output'.repeat(100000)); const type = 3; const armored = PgpArmor.armor(type, source); @@ -2405,14 +2405,14 @@ AAAAAAAAAAAAAAAAzzzzzzzzzzzzzzzzzzzzzzzzzzzz.....`) t.pass(); }); - ava.default(`[unit][PgpArmor.clipIncomplete] correctly handles all the cases`, async t => { + test(`[unit][PgpArmor.clipIncomplete] correctly handles all the cases`, async t => { expect(PgpArmor.clipIncomplete('')).to.be.an.undefined; expect(PgpArmor.clipIncomplete('plain text')).to.be.an.undefined; expect(PgpArmor.clipIncomplete('prefix -----BEGIN PGP MESSAGE-----\n\nexample')).to.equal('-----BEGIN PGP MESSAGE-----\n\nexample'); t.pass(); }); - ava.default(`[unit][ExpirationCache] entry expires after configured interval`, async t => { + test(`[unit][ExpirationCache] entry expires after configured interval`, async t => { const cache = new ExpirationCache(2000); // 2 seconds cache.set('test-key', 'test-value'); expect(cache.get('test-key')).to.equal('test-value'); @@ -2421,12 +2421,12 @@ AAAAAAAAAAAAAAAAzzzzzzzzzzzzzzzzzzzzzzzzzzzz.....`) t.pass(); }); - ava.default(`[unit][Str] splitAlphanumericExtended returns all parts extendec till the end of the original string`, async t => { + test(`[unit][Str] splitAlphanumericExtended returns all parts extendec till the end of the original string`, async t => { expect(Str.splitAlphanumericExtended('part1.part2@part3.part4')).to.eql(['part1.part2@part3.part4', 'part2@part3.part4', 'part3.part4', 'part4']); t.pass(); }); - ava.default(`[unit][MsgUtil.verifyDetached] VerifyRes contains signer fingerprints`, async t => { + test(`[unit][MsgUtil.verifyDetached] VerifyRes contains signer fingerprints`, async t => { const prv = await KeyUtil.parse(rsaPrimaryKeyAndSubkeyBothHavePrivateKey); await KeyUtil.decrypt(prv, '1234'); const plaintext = 'data to sign'; diff --git a/test/source/util/index.ts b/test/source/util/index.ts index 9b3e1b1c8dc..319a353eda6 100644 --- a/test/source/util/index.ts +++ b/test/source/util/index.ts @@ -3,7 +3,6 @@ import * as fs from 'fs'; import { Keyboard, KeyInput } from 'puppeteer'; import { BrowserHandle } from '../browser/browser-handle.js'; -import { TestUrls } from '../browser/test-urls.js'; import { KeyInfoWithIdentityAndOptionalPp, KeyUtil } from '../core/crypto/key.js'; import { SettingsPageRecipe } from '../tests/page-recipe/settings-page-recipe.js'; import { testKeyConstants } from '../tests/tooling/consts'; @@ -65,8 +64,6 @@ interface TestSecretsInterface { /* eslint-enable @typescript-eslint/naming-convention */ export class Config { - public static extensionId = ''; - private static _secrets: TestSecretsInterface; public static secrets = (): TestSecretsInterface => { @@ -128,7 +125,7 @@ export class Util { public static wipeGoogleTokensUsingExperimentalSettingsPage = async (t: AvaContext, browser: BrowserHandle, acct: string) => { for (const wipeTokenBtnSelector of ['@action-wipe-google-refresh-token', '@action-wipe-google-access-token']) { - const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acct)); + const settingsPage = await browser.newExtensionSettingsPage(t, acct); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); const experimentalFrame = await SettingsPageRecipe.awaitNewPageFrame(settingsPage, '@action-open-module-experimental', ['experimental.htm']); await experimentalFrame.waitAndClick(wipeTokenBtnSelector);