From 264ad581ef7a9855b6a2bdbf026f2a5082309497 Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 13:35:39 +0200 Subject: [PATCH 01/22] Upgrade to Puppeteer 11 --- package-lock.json | 242 ++++++++++++++++++++----------------- package.json | 2 +- test/source/tests/gmail.ts | 12 +- 3 files changed, 139 insertions(+), 117 deletions(-) diff --git a/package-lock.json b/package-lock.json index dacbbdca86f..68fb0971365 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "openpgp": "4.10.10", "postcss-html": "^1.2.0", "squire-rte": "1.11.3", - "sweetalert2": "^11.1.9", + "sweetalert2": "11.1.9", "zxcvbn": "4.4.2" }, "devDependencies": { @@ -47,7 +47,7 @@ "mkdirp": "1.0.4", "openpgp": "4.10.10", "pdfjs-dist": "2.10.377", - "puppeteer": "10.2.0", + "puppeteer": "11.0.0", "stylelint": "14.0.1", "stylelint-config-standard": "23.0.0", "tslint": "6.1.3", @@ -2468,9 +2468,9 @@ "dev": true }, "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -5928,6 +5928,12 @@ "node": ">=10" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, "node_modules/moment": { "version": "2.29.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", @@ -6110,10 +6116,13 @@ } }, "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, "engines": { "node": "4.x || >=6.0.0" } @@ -7089,36 +7098,48 @@ } }, "node_modules/puppeteer": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-10.2.0.tgz", - "integrity": "sha512-OR2CCHRashF+f30+LBOtAjK6sNtz2HEyTr5FqAvhf8lR/qB3uBRoIZOwQKgwoyZnMBsxX7ZdazlyBgGjpnkiMw==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-11.0.0.tgz", + "integrity": "sha512-6rPFqN1ABjn4shgOICGDBITTRV09EjXVqhDERBDKwCLz0UyBxeeBH6Ay0vQUJ84VACmlxwzOIzVEJXThcF3aNg==", "dev": true, "hasInstallScript": true, "dependencies": { - "debug": "4.3.1", + "debug": "4.3.2", "devtools-protocol": "0.0.901419", "extract-zip": "2.0.1", "https-proxy-agent": "5.0.0", - "node-fetch": "2.6.1", + "node-fetch": "2.6.5", "pkg-dir": "4.2.0", - "progress": "2.0.1", + "progress": "2.0.3", "proxy-from-env": "1.1.0", "rimraf": "3.0.2", - "tar-fs": "2.0.0", - "unbzip2-stream": "1.3.3", - "ws": "7.4.6" + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.2.3" }, "engines": { "node": ">=10.18.1" } }, - "node_modules/puppeteer/node_modules/progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz", - "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==", + "node_modules/puppeteer/node_modules/ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", "dev": true, "engines": { - "node": ">=0.4.0" + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/qs": { @@ -8221,23 +8242,6 @@ "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true }, - "node_modules/stylelint/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/stylelint/node_modules/import-lazy": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", @@ -8433,27 +8437,15 @@ } }, "node_modules/tar-fs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz", - "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, "dependencies": { "chownr": "^1.1.1", - "mkdirp": "^0.5.1", + "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.0.0" - } - }, - "node_modules/tar-fs/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" + "tar-stream": "^2.1.4" } }, "node_modules/tar-stream": { @@ -8618,6 +8610,12 @@ "node": ">=0.8" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, "node_modules/trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", @@ -8804,9 +8802,9 @@ "dev": true }, "node_modules/unbzip2-stream": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz", - "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, "dependencies": { "buffer": "^5.2.1", @@ -9354,6 +9352,12 @@ "url": "https://github.com/yeoman/update-notifier?sponsor=1" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, "node_modules/well-known-symbols": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", @@ -9363,6 +9367,16 @@ "node": ">=6" } }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/when": { "version": "3.7.7", "resolved": "https://registry.npmjs.org/when/-/when-3.7.7.tgz", @@ -11509,9 +11523,9 @@ "dev": true }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { "ms": "2.1.2" @@ -14218,6 +14232,12 @@ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, "moment": { "version": "2.29.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", @@ -14361,10 +14381,13 @@ } }, "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "dev": true + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } }, "node-forge": { "version": "0.10.0", @@ -15086,30 +15109,31 @@ } }, "puppeteer": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-10.2.0.tgz", - "integrity": "sha512-OR2CCHRashF+f30+LBOtAjK6sNtz2HEyTr5FqAvhf8lR/qB3uBRoIZOwQKgwoyZnMBsxX7ZdazlyBgGjpnkiMw==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-11.0.0.tgz", + "integrity": "sha512-6rPFqN1ABjn4shgOICGDBITTRV09EjXVqhDERBDKwCLz0UyBxeeBH6Ay0vQUJ84VACmlxwzOIzVEJXThcF3aNg==", "dev": true, "requires": { - "debug": "4.3.1", + "debug": "4.3.2", "devtools-protocol": "0.0.901419", "extract-zip": "2.0.1", "https-proxy-agent": "5.0.0", - "node-fetch": "2.6.1", + "node-fetch": "2.6.5", "pkg-dir": "4.2.0", - "progress": "2.0.1", + "progress": "2.0.3", "proxy-from-env": "1.1.0", "rimraf": "3.0.2", - "tar-fs": "2.0.0", - "unbzip2-stream": "1.3.3", - "ws": "7.4.6" + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.2.3" }, "dependencies": { - "progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz", - "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==", - "dev": true + "ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "dev": true, + "requires": {} } } }, @@ -15972,15 +15996,6 @@ "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, "import-lazy": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", @@ -16152,26 +16167,15 @@ } }, "tar-fs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz", - "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, "requires": { "chownr": "^1.1.1", - "mkdirp": "^0.5.1", + "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.0.0" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - } + "tar-stream": "^2.1.4" } }, "tar-stream": { @@ -16299,6 +16303,12 @@ "punycode": "^2.1.1" } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, "trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", @@ -16437,9 +16447,9 @@ "dev": true }, "unbzip2-stream": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz", - "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, "requires": { "buffer": "^5.2.1", @@ -16841,12 +16851,28 @@ } } }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, "well-known-symbols": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", "dev": true }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "when": { "version": "3.7.7", "resolved": "https://registry.npmjs.org/when/-/when-3.7.7.tgz", diff --git a/package.json b/package.json index 52399116d65..f25d90be285 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "mkdirp": "1.0.4", "openpgp": "4.10.10", "pdfjs-dist": "2.10.377", - "puppeteer": "10.2.0", + "puppeteer": "11.0.0", "stylelint": "14.0.1", "stylelint-config-standard": "23.0.0", "tslint": "6.1.3", diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index 75dbe76aa11..688c157c64e 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -180,14 +180,10 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test await Util.sleep(2); // wait for search results await gmailPage.page.setOfflineMode(true); // go offline mode await gmailPage.press('Enter'); // open the message - // TODO(@limonte): use the commented line below instead of opening pgp block in a new tab - // once https://github.com/puppeteer/puppeteer/issues/2548 is resolved - // const pgpBlockPage = await gmailPage.getFrame(['pgp_block.htm']); - const urls = await gmailPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 1 }); - const pgpBlockPage = await browser.newPage(t); - await pgpBlockPage.page.setOfflineMode(true); // go offline mode - await pgpBlockPage.page.goto(urls[0]); - await pgpBlockPage.waitForContent('@pgp-block-content', 'this should decrypt even offline'); + const pgpBlockFrame = await gmailPage.getFrame(['pgp_block.htm']); + await gmailPage.page.setOfflineMode(true); // go offline mode + await pgpBlockFrame.frame.goto(await pgpBlockFrame.frame.url()); // reload the frame + await pgpBlockFrame.waitForContent('@pgp-block-content', 'this should decrypt even offline'); })); ava.default('mail.google.com - rendering attachmnents', testWithBrowser('ci.tests.gmail', async (t, browser) => { From 37ae533fca9a6cc5a892f0cf99a0483349baf33c Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 14:41:21 +0200 Subject: [PATCH 02/22] unsuccessful attempt to refactor createSecureDraft, add todo for the future --- test/source/tests/gmail.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index 688c157c64e..20e0172d239 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -1,7 +1,6 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ import * as ava from 'ava'; -import { Page } from 'puppeteer'; import { BrowserHandle, ControllablePage } from './../browser'; import { TestVariant, Util } from './../util'; @@ -44,10 +43,13 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }; const createSecureDraft = async (t: AvaContext, browser: BrowserHandle, gmailPage: ControllablePage, content: string, params: { offline: boolean } = { offline: false }) => { + // TODO(@limonte): for some reason iframe is able to save the draft to the cloud even + // after gmailPage.page.setOfflineMode(true) is called. Probable the puppeteer issue, revisit. + // const composeBoxFrame = await gmailPage.getFrame(['/chrome/elements/compose.htm']); const urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm'], { sleep: 1 }); const composeBox = await browser.newPage(t, urls[0]); if (params.offline) { - await (composeBox.target as Page).setOfflineMode(true); // go offline mode + await composeBox.page.setOfflineMode(true); // go offline mode } await Util.sleep(4); // the draft isn't being saved if start typing without this delay await composeBox.type('@input-body', content, true); From a47e638009051617d070f73e87d5cfce2a2cbe2a Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 15:06:00 +0200 Subject: [PATCH 03/22] Refactor pageHasSecureDraft() to use getFrame() instead of opening new tab --- test/source/tests/gmail.ts | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index 20e0172d239..6c1f174d4cf 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -61,14 +61,14 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test await composeBox.close(); }; - const pageHasSecureDraft = async (t: AvaContext, browser: BrowserHandle, url: string, expectedContent?: string) => { - const secureDraft = await browser.newPage(t, url); + const pageHasSecureDraft = async (gmailPage: ControllablePage, expectedContent?: string) => { + const draftFrame = await gmailPage.getFrame(['/chrome/elements/compose.htm', '&draftId=']); if (expectedContent) { - await secureDraft.waitForContent('@input-body', expectedContent); + await draftFrame.waitForContent('@input-body', expectedContent); } else { - await secureDraft.waitAll('@input-body'); + await draftFrame.waitAll('@input-body'); } - return secureDraft; + return draftFrame; }; const pageDoesNotHaveSecureReplyContainer = async (gmailPage: ControllablePage) => { @@ -266,20 +266,17 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test await gmailPage.waitForContent('#fc_offline_drafts', 'FlowCrypt offline drafts:'); await gmailPage.ensureElementsCount('#fc_offline_drafts a', 2); await gmailPage.waitAndClick('#fc_offline_drafts a'); - let urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm'], { sleep: 1 }); // compose draft 2 should be first in list as drafts are sorted by date descending - const draft = await pageHasSecureDraft(t, browser, urls[0], 'compose draft 2'); + const draft = await pageHasSecureDraft(gmailPage, 'compose draft 2'); await Util.sleep(4); // the draft isn't being saved if start typing without this delay await draft.type('@input-body', 'trigger saving a draft to the cloud', true); await ComposePageRecipe.waitWhenDraftIsSaved(draft); - await draft.close(); // after draft 2 is saved to the cloud, it should be removed from offline drafts await gmailPage.page.reload(); await gmailPage.waitForContent('#fc_offline_drafts', 'FlowCrypt offline drafts:'); await gmailPage.ensureElementsCount('#fc_offline_drafts a', 1); await gmailPage.waitAndClick('#fc_offline_drafts a'); - urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm'], { sleep: 1 }); - await pageHasSecureDraft(t, browser, urls[0], 'compose draft 1'); + await pageHasSecureDraft(gmailPage, 'compose draft 1'); })); ava.default('mail.google.com - secure reply btn, reply draft', testWithBrowser('ci.tests.gmail', async (t, browser) => { @@ -295,14 +292,12 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test await gmailPage.page.reload(); const urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm']); expect(urls.length).to.equal(1); - let replyBox = await pageHasSecureDraft(t, browser, urls[0], 'reply draft'); - await replyBox.close(); + let replyBox = await pageHasSecureDraft(gmailPage, 'reply draft'); await createSecureDraft(t, browser, gmailPage, 'offline reply draft', { offline: true }); await gmailPage.page.reload(); - replyBox = await pageHasSecureDraft(t, browser, urls[0], 'offline reply draft'); + replyBox = await pageHasSecureDraft(gmailPage, 'offline reply draft'); await replyBox.waitAndClick('@action-send'); await replyBox.waitTillGone('@action-send'); - await replyBox.close(); await gmailPage.page.reload(); await gmailPage.waitAndClick('.h7:last-child .ajz', { delay: 1 }); // the small triangle which toggles the message details await gmailPage.waitForContent('.h7:last-child .ajA', 'Re: [ci.test] encrypted email for reply render'); // make sure that the subject of the sent draft is corrent @@ -323,8 +318,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test // veryfy that there are two compose windows: new compose window and secure draft const urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm'], { sleep: 1 }); expect(urls.length).to.equal(2); - const composeDraft = await pageHasSecureDraft(t, browser, urls[1], 'compose draft'); - await composeDraft.close(); + await pageHasSecureDraft(gmailPage, 'compose draft'); // try to open 4 compose windows at the same time await gmailPage.waitAndClick('@action-secure-compose', { delay: 1 }); await gmailPage.waitAndClick('@action-secure-compose', { delay: 1 }); From b2a2e5694edb6a8466bd1e64369736360dcdd9f2 Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 15:36:59 +0200 Subject: [PATCH 04/22] use getFrame() in Thunderbird tests --- test/source/tests/gmail.ts | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index 6c1f174d4cf..e32f91d9250 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -213,13 +213,9 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test const signature = ['Limon.Monte@Gmail.Com', 'matching signature']; await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { params: url, content: ['1234'], signature }); await pageHasSecureReplyContainer(t, browser, gmailPage); - // validate pgp_pubkey.htm is rendered - const pgpPubkeyUrls = await gmailPage.getFramesUrls(['/chrome/elements/pgp_pubkey.htm'], { sleep: 10, appearIn: 20 }); - expect(pgpPubkeyUrls.length).to.equal(1); - await pageHasSecureReplyContainer(t, browser, gmailPage); await testMinimumElementHeight(gmailPage, '.pgp_block.signedMsg', 80); await testMinimumElementHeight(gmailPage, '.pgp_block.publicKey', 120); - const pubkeyPage = await browser.newPage(t, pgpPubkeyUrls[0]); + const pubkeyPage = await gmailPage.getFrame(['/chrome/elements/pgp_pubkey.htm']); await pubkeyPage.waitForContent('@container-pgp-pubkey', 'Fingerprint: 50B7 A032 B5E1 FBAB 24BA B205 B362 45FD AC2F BF3D'); })); @@ -234,11 +230,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test const signature = ['Limon.Monte@Gmail.Com', 'matching signature']; await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { params: url, content: ['1234'], signature }); await pageHasSecureReplyContainer(t, browser, gmailPage); - // validate pgp_pubkey.htm is rendered - const pgpPubkeyUrls = await gmailPage.getFramesUrls(['/chrome/elements/pgp_pubkey.htm'], { sleep: 10, appearIn: 20 }); - expect(pgpPubkeyUrls.length).to.equal(1); - await pageHasSecureReplyContainer(t, browser, gmailPage); - const pubkeyPage = await browser.newPage(t, pgpPubkeyUrls[0]); + const pubkeyPage = await gmailPage.getFrame(['/chrome/elements/pgp_pubkey.htm']); await pubkeyPage.waitForContent('@container-pgp-pubkey', 'Fingerprint: 50B7 A032 B5E1 FBAB 24BA B205 B362 45FD AC2F BF3D'); })); @@ -247,10 +239,8 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test const pgpBlockUrls = await gmailPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 10, appearIn: 20 }); const url = pgpBlockUrls[0].split('/chrome/elements/pgp_block.htm')[1]; await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { params: url, content: ['Encrypted Subject: [ci.test] Thunderbird html signed + encrypted', '1234'] }); - const urls = await gmailPage.getFramesUrls(['/chrome/elements/pgp_pubkey.htm'], { sleep: 10, appearIn: 20 }); - expect(urls.length).to.equal(1); await pageHasSecureReplyContainer(t, browser, gmailPage); - const pubkeyPage = await browser.newPage(t, urls[0]); + const pubkeyPage = await gmailPage.getFrame(['/chrome/elements/pgp_pubkey.htm']); await pubkeyPage.waitForContent('@container-pgp-pubkey', 'Fingerprint: 50B7 A032 B5E1 FBAB 24BA B205 B362 45FD AC2F BF3D'); })); @@ -297,6 +287,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test await gmailPage.page.reload(); replyBox = await pageHasSecureDraft(gmailPage, 'offline reply draft'); await replyBox.waitAndClick('@action-send'); + console.log(await gmailPage.page.screenshot({ encoding: 'base64' })); await replyBox.waitTillGone('@action-send'); await gmailPage.page.reload(); await gmailPage.waitAndClick('.h7:last-child .ajz', { delay: 1 }); // the small triangle which toggles the message details From 52770d725387d23eb1b3163ab3241e5b0fa3b0e2 Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 16:40:01 +0200 Subject: [PATCH 05/22] workaround sending in the 'secure reply btn, reply draft' test --- test/source/tests/gmail.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index e32f91d9250..fdff8c12c48 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -286,8 +286,9 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test await createSecureDraft(t, browser, gmailPage, 'offline reply draft', { offline: true }); await gmailPage.page.reload(); replyBox = await pageHasSecureDraft(gmailPage, 'offline reply draft'); - await replyBox.waitAndClick('@action-send'); - console.log(await gmailPage.page.screenshot({ encoding: 'base64' })); + // await replyBox.waitAndClick('@action-send'); doesn't work for some reason, use keyboard instead + await gmailPage.page.keyboard.press('Tab'); + await gmailPage.page.keyboard.press('Enter'); await replyBox.waitTillGone('@action-send'); await gmailPage.page.reload(); await gmailPage.waitAndClick('.h7:last-child .ajz', { delay: 1 }); // the small triangle which toggles the message details From c22ddb77608746ae7b90787e7b0f34e1353de0bc Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 17:00:59 +0200 Subject: [PATCH 06/22] Simplify openGmailPage() --- test/source/tests/gmail.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index fdff8c12c48..6631fc76271 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -62,13 +62,13 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }; const pageHasSecureDraft = async (gmailPage: ControllablePage, expectedContent?: string) => { - const draftFrame = await gmailPage.getFrame(['/chrome/elements/compose.htm', '&draftId=']); + const secureDraftFrame = await gmailPage.getFrame(['/chrome/elements/compose.htm', '&draftId=']); if (expectedContent) { - await draftFrame.waitForContent('@input-body', expectedContent); + await secureDraftFrame.waitForContent('@input-body', expectedContent); } else { - await draftFrame.waitAll('@input-body'); + await secureDraftFrame.waitAll('@input-body'); } - return draftFrame; + return secureDraftFrame; }; const pageDoesNotHaveSecureReplyContainer = async (gmailPage: ControllablePage) => { @@ -78,12 +78,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test const openGmailPage = async (t: AvaContext, browser: BrowserHandle, path: string): Promise => { const url = TestUrls.gmail(0, path); - const gmailPage = await browser.newPage(t, url); - await gmailPage.waitAll('@action-secure-compose'); - if (path) { // gmail does weird things with navigation sometimes, nudge it again - await gmailPage.goto(url); - } - return gmailPage; + return await browser.newPage(t, url); }; const gotoGmailPage = async (gmailPage: ControllablePage, path: string, category: GmailCategory = 'inbox') => { From 90b170b2858141646b431004a4ae47704ff1295b Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 17:15:52 +0200 Subject: [PATCH 07/22] fail faster - add timeout param to waitAndClick() --- test/source/browser/controllable.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/source/browser/controllable.ts b/test/source/browser/controllable.ts index 277a538c307..f9fb72eef12 100644 --- a/test/source/browser/controllable.ts +++ b/test/source/browser/controllable.ts @@ -273,11 +273,11 @@ abstract class ControllableBase { await this.waitAndClick(`@ui-modal-${type}-${clickBtn}`); } - public waitAndClick = async (selector: string, { delay = 0.1, confirmGone = false, retryErrs = false, sleepWhenDone }: - { delay?: number, confirmGone?: boolean, retryErrs?: boolean, sleepWhenDone?: number } = {}) => { + public waitAndClick = async (selector: string, { delay = 0.1, timeout = 10000, confirmGone = false, retryErrs = false, sleepWhenDone }: + { delay?: number, timeout?: number, confirmGone?: boolean, retryErrs?: boolean, sleepWhenDone?: number } = {}) => { for (const i of [1, 2, 3]) { this.log(`wait_and_click(i${i}):1:${selector}`); - await this.waitAll(selector); + await this.waitAll(selector, { timeout }); this.log(`wait_and_click(i${i}):2:${selector}`); await Util.sleep(delay); this.log(`wait_and_click(i${i}):3:${selector}`); From 2a1e72c8ec700c4a66ac86c25123f40c26567bb9 Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 17:24:09 +0200 Subject: [PATCH 08/22] wip --- test/source/browser/controllable.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/source/browser/controllable.ts b/test/source/browser/controllable.ts index f9fb72eef12..ae7289a8308 100644 --- a/test/source/browser/controllable.ts +++ b/test/source/browser/controllable.ts @@ -289,6 +289,7 @@ abstract class ControllableBase { } catch (e) { this.log(`wait_and_click(i${i}):6:err(${String(e)}):${selector}`); if (e.message === 'Node is either not visible or not an HTMLElement' || e.message === 'Node is detached from document') { + console.log(await (this.target as Page).screenshot({ encoding: 'base64' })); // maybe the node just re-rendered? if (!retryErrs || i === 3) { e.stack = `[clicking(${selector}) failed because element quickly disappeared, consider adding retryErrs]\n` + e.stack; From 7999b263c43603c4120a64d688bd3ed00f3afbdf Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 17:38:27 +0200 Subject: [PATCH 09/22] handle 'Node is either not clickable' error --- test/source/browser/controllable.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/source/browser/controllable.ts b/test/source/browser/controllable.ts index ae7289a8308..9f84b2638a0 100644 --- a/test/source/browser/controllable.ts +++ b/test/source/browser/controllable.ts @@ -288,7 +288,12 @@ abstract class ControllableBase { break; } catch (e) { this.log(`wait_and_click(i${i}):6:err(${String(e)}):${selector}`); - if (e.message === 'Node is either not visible or not an HTMLElement' || e.message === 'Node is detached from document') { + if ( + e.message === 'Node is either not visible or not an HTMLElement' || + e.message === 'Node is either not clickable or not an HTMLElement' || + e.message === 'Node is detached from document' + ) { + console.log(selector); console.log(await (this.target as Page).screenshot({ encoding: 'base64' })); // maybe the node just re-rendered? if (!retryErrs || i === 3) { From 20d6d7c3927fe2e3ff78aa4b38636fa55b180809 Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 17:58:48 +0200 Subject: [PATCH 10/22] wait longer for @action-step0 and @action-step1 --- test/source/browser/controllable.ts | 2 -- test/source/tests/gmail.ts | 4 ++-- test/source/tests/page-recipe/setup-page-recipe.ts | 8 ++++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/test/source/browser/controllable.ts b/test/source/browser/controllable.ts index 9f84b2638a0..277679d636d 100644 --- a/test/source/browser/controllable.ts +++ b/test/source/browser/controllable.ts @@ -293,8 +293,6 @@ abstract class ControllableBase { e.message === 'Node is either not clickable or not an HTMLElement' || e.message === 'Node is detached from document' ) { - console.log(selector); - console.log(await (this.target as Page).screenshot({ encoding: 'base64' })); // maybe the node just re-rendered? if (!retryErrs || i === 3) { e.stack = `[clicking(${selector}) failed because element quickly disappeared, consider adding retryErrs]\n` + e.stack; diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index 6631fc76271..30ac0d2f530 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -51,7 +51,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test if (params.offline) { await composeBox.page.setOfflineMode(true); // go offline mode } - await Util.sleep(4); // the draft isn't being saved if start typing without this delay + await Util.sleep(5); // the draft isn't being saved if start typing without this delay await composeBox.type('@input-body', content, true); if (params.offline) { await ComposePageRecipe.waitWhenDraftIsSavedLocally(composeBox); @@ -253,7 +253,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test await gmailPage.waitAndClick('#fc_offline_drafts a'); // compose draft 2 should be first in list as drafts are sorted by date descending const draft = await pageHasSecureDraft(gmailPage, 'compose draft 2'); - await Util.sleep(4); // the draft isn't being saved if start typing without this delay + await Util.sleep(5); // the draft isn't being saved if start typing without this delay await draft.type('@input-body', 'trigger saving a draft to the cloud', true); await ComposePageRecipe.waitWhenDraftIsSaved(draft); // after draft 2 is saved to the cloud, it should be removed from offline drafts diff --git a/test/source/tests/page-recipe/setup-page-recipe.ts b/test/source/tests/page-recipe/setup-page-recipe.ts index 3c663186c9b..25d27c29189 100644 --- a/test/source/tests/page-recipe/setup-page-recipe.ts +++ b/test/source/tests/page-recipe/setup-page-recipe.ts @@ -108,9 +108,9 @@ export class SetupPageRecipe extends PageRecipe { ) { if (!noPrvCreateOrgRule) { if (usedPgpBefore) { - await settingsPage.waitAndClick('@action-step0foundkey-choose-manual-enter', { retryErrs: true }); + await settingsPage.waitAndClick('@action-step0foundkey-choose-manual-enter', { timeout: 30000, retryErrs: true }); } else { - await settingsPage.waitAndClick('@action-step1easyormanual-choose-manual-enter', { retryErrs: true }); + await settingsPage.waitAndClick('@action-step1easyormanual-choose-manual-enter', { timeout: 30000, retryErrs: true }); } } key = key || Config.key(keyTitle); @@ -284,9 +284,9 @@ export class SetupPageRecipe extends PageRecipe { private static createBegin = async (settingsPage: ControllablePage, keyTitle: string, { key, usedPgpBefore = false }: { key?: { passphrase: string }, usedPgpBefore?: boolean } = {}) => { const k = key || Config.key(keyTitle); if (usedPgpBefore) { - await settingsPage.waitAndClick('@action-step0foundkey-choose-manual-create'); + await settingsPage.waitAndClick('@action-step0foundkey-choose-manual-create', { timeout: 30000 }); } else { - await settingsPage.waitAndClick('@action-step1easyormanual-choose-manual-create', { retryErrs: true }); + await settingsPage.waitAndClick('@action-step1easyormanual-choose-manual-create', { timeout: 30000, retryErrs: true }); } await settingsPage.waitAndType('@input-step2bmanualcreate-passphrase-1', k.passphrase); await settingsPage.waitAndType('@input-step2bmanualcreate-passphrase-2', k.passphrase); From 65829ae604d7ac04ef3aaa2df3d379148808ecdc Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 18:21:02 +0200 Subject: [PATCH 11/22] wait longer for @input-compatibility-fix-expire-years --- test/source/tests/page-recipe/setup-page-recipe.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/source/tests/page-recipe/setup-page-recipe.ts b/test/source/tests/page-recipe/setup-page-recipe.ts index 25d27c29189..ba114aef92f 100644 --- a/test/source/tests/page-recipe/setup-page-recipe.ts +++ b/test/source/tests/page-recipe/setup-page-recipe.ts @@ -186,7 +186,7 @@ export class SetupPageRecipe extends PageRecipe { } await settingsPage.waitAndClick('@input-step2bmanualenter-save', { delay: 1 }); if (fixKey) { - await settingsPage.waitAll('@input-compatibility-fix-expire-years'); + await settingsPage.waitAll('@input-compatibility-fix-expire-years', { timeout: 30000 }); await settingsPage.selectOption('@input-compatibility-fix-expire-years', '1'); await settingsPage.waitAndClick('@action-fix-and-import-key'); } From 09e0283f57f0fde8f0a4e175064d418506c7c96a Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 18:37:13 +0200 Subject: [PATCH 12/22] wip --- .../tests/page-recipe/compose-page-recipe.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/source/tests/page-recipe/compose-page-recipe.ts b/test/source/tests/page-recipe/compose-page-recipe.ts index 3d59048acb6..5da0305db06 100644 --- a/test/source/tests/page-recipe/compose-page-recipe.ts +++ b/test/source/tests/page-recipe/compose-page-recipe.ts @@ -8,6 +8,7 @@ import { EvaluateFn } from 'puppeteer'; import { PageRecipe } from './abstract-page-recipe'; import { Util } from '../../util'; import { expect } from 'chai'; +import { Page } from 'puppeteer'; type RecipientType = "to" | "cc" | "bcc"; type Recipients = { @@ -106,11 +107,23 @@ export class ComposePageRecipe extends PageRecipe { } public static waitWhenDraftIsSaved = async (composePageOrFrame: Controllable) => { - await composePageOrFrame.verifyContentIsPresentContinuously('@send-btn-note', 'Saved'); + try { + await composePageOrFrame.verifyContentIsPresentContinuously('@send-btn-note', 'Saved'); + } catch (e) { + console.log('waitWhenDraftIsSaved'); + console.log(e); + console.log(await (composePageOrFrame.target as Page).screenshot({ encoding: 'base64' })); + } } public static waitWhenDraftIsSavedLocally = async (composePageOrFrame: Controllable) => { - await composePageOrFrame.verifyContentIsPresentContinuously('@send-btn-note', 'Draft saved locally (offline)'); + try { + await composePageOrFrame.verifyContentIsPresentContinuously('@send-btn-note', 'Draft saved locally (offline)'); + } catch (e) { + console.log('waitWhenDraftIsSaved'); + console.log(e); + console.log(await (composePageOrFrame.target as Page).screenshot({ encoding: 'base64' })); + } } public static sendAndClose = async ( From ac25d440fc1fa5c85386f6596c18607221135ef3 Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 22:41:55 +0200 Subject: [PATCH 13/22] always delete local draft after sending --- .../elements/compose-modules/compose-draft-module.ts | 5 ++--- test/source/tests/gmail.ts | 9 ++++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/extension/chrome/elements/compose-modules/compose-draft-module.ts b/extension/chrome/elements/compose-modules/compose-draft-module.ts index 022bafeb605..356b6308bcc 100644 --- a/extension/chrome/elements/compose-modules/compose-draft-module.ts +++ b/extension/chrome/elements/compose-modules/compose-draft-module.ts @@ -94,11 +94,10 @@ export class ComposeDraftModule extends ViewModule { await Ui.time.wait(() => !this.currentlySavingDraft ? true : undefined); if (this.view.draftId) { try { - if (this.isLocalDraftId(this.view.draftId)) { - await this.localDraftRemove(); - } else { + if (!this.isLocalDraftId(this.view.draftId)) { await this.view.emailProvider.draftDelete(this.view.draftId); } + await this.localDraftRemove(); this.view.draftId = ''; } catch (e) { if (ApiErr.isAuthErr(e)) { diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index 30ac0d2f530..c4738485399 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -265,8 +265,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test })); ava.default('mail.google.com - secure reply btn, reply draft', testWithBrowser('ci.tests.gmail', async (t, browser) => { - const gmailPage = await openGmailPage(t, browser, '/'); - await gotoGmailPage(gmailPage, '/FMfcgzGkbDRNgcPktjdSxpJVhZlZqpTr'); // to go encrypted convo + const gmailPage = await openGmailPage(t, browser, '/FMfcgzGlkjftvKTsGnTltMvmZdDzdPFB'); // to go encrypted convo // Gmail has 100 emails per thread limit, so if there are 98 deleted messages + 1 initial message, // the draft number 100 won't be saved. Therefore, we need to delete forever trashed messages from this thread. if (await gmailPage.isElementPresent('//*[text()="delete forever"]')) { @@ -274,18 +273,18 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test } await gmailPage.waitAndClick('@secure-reply-button'); await createSecureDraft(t, browser, gmailPage, 'reply draft'); - await gmailPage.page.reload(); + await gmailPage.page.reload({ waitUntil: 'networkidle2' }); const urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm']); expect(urls.length).to.equal(1); let replyBox = await pageHasSecureDraft(gmailPage, 'reply draft'); await createSecureDraft(t, browser, gmailPage, 'offline reply draft', { offline: true }); - await gmailPage.page.reload(); + await gmailPage.page.reload({ waitUntil: 'networkidle2' }); replyBox = await pageHasSecureDraft(gmailPage, 'offline reply draft'); // await replyBox.waitAndClick('@action-send'); doesn't work for some reason, use keyboard instead await gmailPage.page.keyboard.press('Tab'); await gmailPage.page.keyboard.press('Enter'); await replyBox.waitTillGone('@action-send'); - await gmailPage.page.reload(); + await gmailPage.page.reload({ waitUntil: 'networkidle2' }); await gmailPage.waitAndClick('.h7:last-child .ajz', { delay: 1 }); // the small triangle which toggles the message details await gmailPage.waitForContent('.h7:last-child .ajA', 'Re: [ci.test] encrypted email for reply render'); // make sure that the subject of the sent draft is corrent await GmailPageRecipe.deleteLastReply(gmailPage); From f80ab4b158cade2fe7f0463c0b37768b2962e25b Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 22:57:37 +0200 Subject: [PATCH 14/22] cleanup --- .../tests/page-recipe/compose-page-recipe.ts | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/test/source/tests/page-recipe/compose-page-recipe.ts b/test/source/tests/page-recipe/compose-page-recipe.ts index 5da0305db06..3d59048acb6 100644 --- a/test/source/tests/page-recipe/compose-page-recipe.ts +++ b/test/source/tests/page-recipe/compose-page-recipe.ts @@ -8,7 +8,6 @@ import { EvaluateFn } from 'puppeteer'; import { PageRecipe } from './abstract-page-recipe'; import { Util } from '../../util'; import { expect } from 'chai'; -import { Page } from 'puppeteer'; type RecipientType = "to" | "cc" | "bcc"; type Recipients = { @@ -107,23 +106,11 @@ export class ComposePageRecipe extends PageRecipe { } public static waitWhenDraftIsSaved = async (composePageOrFrame: Controllable) => { - try { - await composePageOrFrame.verifyContentIsPresentContinuously('@send-btn-note', 'Saved'); - } catch (e) { - console.log('waitWhenDraftIsSaved'); - console.log(e); - console.log(await (composePageOrFrame.target as Page).screenshot({ encoding: 'base64' })); - } + await composePageOrFrame.verifyContentIsPresentContinuously('@send-btn-note', 'Saved'); } public static waitWhenDraftIsSavedLocally = async (composePageOrFrame: Controllable) => { - try { - await composePageOrFrame.verifyContentIsPresentContinuously('@send-btn-note', 'Draft saved locally (offline)'); - } catch (e) { - console.log('waitWhenDraftIsSaved'); - console.log(e); - console.log(await (composePageOrFrame.target as Page).screenshot({ encoding: 'base64' })); - } + await composePageOrFrame.verifyContentIsPresentContinuously('@send-btn-note', 'Draft saved locally (offline)'); } public static sendAndClose = async ( From f069f695b707388973d9a845254a42af332c7fba Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 23:25:37 +0200 Subject: [PATCH 15/22] rename mock live test --- ...l for reply render (FMfcgzGlkjftvKTsGnTltMvmZdDzdPFB).eml} | 0 test/source/tests/gmail.ts | 4 +--- 2 files changed, 1 insertion(+), 3 deletions(-) rename test/source/mock/google/live-gmail-test-emails/{[ci.test] encrypted email for reply render (FMfcgzGkbDRNgcPktjdSxpJVhZlZqpTr).eml => [ci.test] encrypted email for reply render (FMfcgzGlkjftvKTsGnTltMvmZdDzdPFB).eml} (100%) diff --git a/test/source/mock/google/live-gmail-test-emails/[ci.test] encrypted email for reply render (FMfcgzGkbDRNgcPktjdSxpJVhZlZqpTr).eml b/test/source/mock/google/live-gmail-test-emails/[ci.test] encrypted email for reply render (FMfcgzGlkjftvKTsGnTltMvmZdDzdPFB).eml similarity index 100% rename from test/source/mock/google/live-gmail-test-emails/[ci.test] encrypted email for reply render (FMfcgzGkbDRNgcPktjdSxpJVhZlZqpTr).eml rename to test/source/mock/google/live-gmail-test-emails/[ci.test] encrypted email for reply render (FMfcgzGlkjftvKTsGnTltMvmZdDzdPFB).eml diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index c4738485399..225598e1335 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -280,9 +280,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test await createSecureDraft(t, browser, gmailPage, 'offline reply draft', { offline: true }); await gmailPage.page.reload({ waitUntil: 'networkidle2' }); replyBox = await pageHasSecureDraft(gmailPage, 'offline reply draft'); - // await replyBox.waitAndClick('@action-send'); doesn't work for some reason, use keyboard instead - await gmailPage.page.keyboard.press('Tab'); - await gmailPage.page.keyboard.press('Enter'); + await replyBox.waitAndClick('@action-send'); await replyBox.waitTillGone('@action-send'); await gmailPage.page.reload({ waitUntil: 'networkidle2' }); await gmailPage.waitAndClick('.h7:last-child .ajz', { delay: 1 }); // the small triangle which toggles the message details From 254ff2f1ca69f89007c4c686b01e2f5e175f919d Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Sun, 7 Nov 2021 23:38:12 +0200 Subject: [PATCH 16/22] log --- test/source/tests/gmail.ts | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index 225598e1335..7e7bca63919 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -53,22 +53,39 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test } await Util.sleep(5); // the draft isn't being saved if start typing without this delay await composeBox.type('@input-body', content, true); - if (params.offline) { - await ComposePageRecipe.waitWhenDraftIsSavedLocally(composeBox); - } else { - await ComposePageRecipe.waitWhenDraftIsSaved(composeBox); + try { + if (params.offline) { + await ComposePageRecipe.waitWhenDraftIsSavedLocally(composeBox); + } else { + await ComposePageRecipe.waitWhenDraftIsSaved(composeBox); + } + } catch (e) { + console.log('waitWhenDraftIsSaved'); + console.log(await gmailPage.screenshot()); + throw e; } await composeBox.close(); }; const pageHasSecureDraft = async (gmailPage: ControllablePage, expectedContent?: string) => { - const secureDraftFrame = await gmailPage.getFrame(['/chrome/elements/compose.htm', '&draftId=']); - if (expectedContent) { - await secureDraftFrame.waitForContent('@input-body', expectedContent); - } else { - await secureDraftFrame.waitAll('@input-body'); + try { + console.log('pageHasSecureDraft BEFORE getFrame'); + const urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm']); + console.log(urls); + const secureDraftFrame = await gmailPage.getFrame(['/chrome/elements/compose.htm', '&draftId='], { timeout: 20 }); + if (expectedContent) { + await secureDraftFrame.waitForContent('@input-body', expectedContent); + } else { + await secureDraftFrame.waitAll('@input-body'); + } + return secureDraftFrame; + } catch (e) { + console.log('pageHasSecureDraft'); + const urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm']); + console.log(urls); + console.log(await gmailPage.screenshot()); + throw e; } - return secureDraftFrame; }; const pageDoesNotHaveSecureReplyContainer = async (gmailPage: ControllablePage) => { From cc2f6f91ffaadd9bce423d87ebfa45e802660228 Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Mon, 8 Nov 2021 01:37:11 +0200 Subject: [PATCH 17/22] fix 'secure reply btn, reply draft' test --- test/source/tests/gmail.ts | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index 7e7bca63919..756952105a6 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -43,19 +43,23 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }; const createSecureDraft = async (t: AvaContext, browser: BrowserHandle, gmailPage: ControllablePage, content: string, params: { offline: boolean } = { offline: false }) => { - // TODO(@limonte): for some reason iframe is able to save the draft to the cloud even - // after gmailPage.page.setOfflineMode(true) is called. Probable the puppeteer issue, revisit. - // const composeBoxFrame = await gmailPage.getFrame(['/chrome/elements/compose.htm']); - const urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm'], { sleep: 1 }); - const composeBox = await browser.newPage(t, urls[0]); + let composeBox; if (params.offline) { + // TODO(@limonte): for some reason iframe is able to save the draft to the cloud even + // after gmailPage.page.setOfflineMode(true) is called. Probable the puppeteer issue, revisit. + // const composeBoxFrame = await gmailPage.getFrame(['/chrome/elements/compose.htm']); + const urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm'], { sleep: 1 }); + composeBox = await browser.newPage(t, urls[0]); await composeBox.page.setOfflineMode(true); // go offline mode + } else { + composeBox = await gmailPage.getFrame(['/chrome/elements/compose.htm']); } await Util.sleep(5); // the draft isn't being saved if start typing without this delay await composeBox.type('@input-body', content, true); try { if (params.offline) { await ComposePageRecipe.waitWhenDraftIsSavedLocally(composeBox); + await (composeBox as ControllablePage).close(); } else { await ComposePageRecipe.waitWhenDraftIsSaved(composeBox); } @@ -64,7 +68,6 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test console.log(await gmailPage.screenshot()); throw e; } - await composeBox.close(); }; const pageHasSecureDraft = async (gmailPage: ControllablePage, expectedContent?: string) => { @@ -290,14 +293,12 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test } await gmailPage.waitAndClick('@secure-reply-button'); await createSecureDraft(t, browser, gmailPage, 'reply draft'); - await gmailPage.page.reload({ waitUntil: 'networkidle2' }); - const urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm']); - expect(urls.length).to.equal(1); - let replyBox = await pageHasSecureDraft(gmailPage, 'reply draft'); await createSecureDraft(t, browser, gmailPage, 'offline reply draft', { offline: true }); await gmailPage.page.reload({ waitUntil: 'networkidle2' }); - replyBox = await pageHasSecureDraft(gmailPage, 'offline reply draft'); - await replyBox.waitAndClick('@action-send'); + const replyBox = await pageHasSecureDraft(gmailPage, 'offline reply draft'); + // await replyBox.waitAndClick('@action-send'); doesn't work for some reason, use keyboard instead + await gmailPage.page.keyboard.press('Tab'); + await gmailPage.page.keyboard.press('Enter'); await replyBox.waitTillGone('@action-send'); await gmailPage.page.reload({ waitUntil: 'networkidle2' }); await gmailPage.waitAndClick('.h7:last-child .ajz', { delay: 1 }); // the small triangle which toggles the message details From dfd8693d1e71e052905cb867c8b2f0177dabe561 Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Mon, 8 Nov 2021 01:49:00 +0200 Subject: [PATCH 18/22] cleanup --- test/source/tests/gmail.ts | 39 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index 756952105a6..e1b5e8cc0b8 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -56,39 +56,22 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test } await Util.sleep(5); // the draft isn't being saved if start typing without this delay await composeBox.type('@input-body', content, true); - try { - if (params.offline) { - await ComposePageRecipe.waitWhenDraftIsSavedLocally(composeBox); - await (composeBox as ControllablePage).close(); - } else { - await ComposePageRecipe.waitWhenDraftIsSaved(composeBox); - } - } catch (e) { - console.log('waitWhenDraftIsSaved'); - console.log(await gmailPage.screenshot()); - throw e; + if (params.offline) { + await ComposePageRecipe.waitWhenDraftIsSavedLocally(composeBox); + await (composeBox as ControllablePage).close(); + } else { + await ComposePageRecipe.waitWhenDraftIsSaved(composeBox); } }; const pageHasSecureDraft = async (gmailPage: ControllablePage, expectedContent?: string) => { - try { - console.log('pageHasSecureDraft BEFORE getFrame'); - const urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm']); - console.log(urls); - const secureDraftFrame = await gmailPage.getFrame(['/chrome/elements/compose.htm', '&draftId='], { timeout: 20 }); - if (expectedContent) { - await secureDraftFrame.waitForContent('@input-body', expectedContent); - } else { - await secureDraftFrame.waitAll('@input-body'); - } - return secureDraftFrame; - } catch (e) { - console.log('pageHasSecureDraft'); - const urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm']); - console.log(urls); - console.log(await gmailPage.screenshot()); - throw e; + const secureDraftFrame = await gmailPage.getFrame(['/chrome/elements/compose.htm', '&draftId=']); + if (expectedContent) { + await secureDraftFrame.waitForContent('@input-body', expectedContent); + } else { + await secureDraftFrame.waitAll('@input-body'); } + return secureDraftFrame; }; const pageDoesNotHaveSecureReplyContainer = async (gmailPage: ControllablePage) => { From 5b223c2ed7f34dda18fdf8f1809b650d829cb854 Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Mon, 8 Nov 2021 20:27:07 +0200 Subject: [PATCH 19/22] do not rely on sleep timeouts --- test/source/tests/gmail.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index e1b5e8cc0b8..797af59bfdc 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -331,13 +331,12 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test ava.default('mail.google.com - plain reply draft', testWithBrowser('ci.tests.gmail', async (t, browser) => { const gmailPage = await openGmailPage(t, browser, '/FMfcgzGkbDRNgcPktjdSxpJVhZlZqpTr'); // encrypted convo await gmailPage.waitAndClick('[data-tooltip="Reply"]'); - await Util.sleep(5); + await gmailPage.waitTillFocusIsIn('div[aria-label="Message Body"]'); await gmailPage.type('div[aria-label="Message Body"]', 'plain reply', true); - await gotoGmailPage(gmailPage, '/'); // go to Inbox - await Util.sleep(1); - await gotoGmailPage(gmailPage, '/FMfcgzGkbDRNgcPktjdSxpJVhZlZqpTr'); // go back to encrypted convo with plain reply + await gmailPage.waitForContent('.oG.aOy', 'Draft saved'); + await gmailPage.page.reload({ waitUntil: 'networkidle2' }); await pageDoesNotHaveSecureReplyContainer(gmailPage); - await gmailPage.waitForContent('div[aria-label="Message Body"]', 'plain reply'); + await gmailPage.waitForContent('div[aria-label="Message Body"]', 'plain reply', 30); await gmailPage.click('[aria-label^="Discard draft"]'); })); From 728e967dee12f8240694978b002eb6bd06236d67 Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Mon, 8 Nov 2021 21:39:58 +0200 Subject: [PATCH 20/22] typo --- test/source/tests/gmail.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index 797af59bfdc..4c63c8b2a62 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -46,7 +46,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test let composeBox; if (params.offline) { // TODO(@limonte): for some reason iframe is able to save the draft to the cloud even - // after gmailPage.page.setOfflineMode(true) is called. Probable the puppeteer issue, revisit. + // after gmailPage.page.setOfflineMode(true) is called. Probably, the puppeteer issue, revisit. // const composeBoxFrame = await gmailPage.getFrame(['/chrome/elements/compose.htm']); const urls = await gmailPage.getFramesUrls(['/chrome/elements/compose.htm'], { sleep: 1 }); composeBox = await browser.newPage(t, urls[0]); From 78cb57366a831dcb79d57b80d30bfabcfe56fcfa Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Tue, 9 Nov 2021 10:26:53 +0200 Subject: [PATCH 21/22] timeout in seconds --- test/source/browser/controllable.ts | 2 +- test/source/tests/page-recipe/setup-page-recipe.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/source/browser/controllable.ts b/test/source/browser/controllable.ts index 277679d636d..d89639973da 100644 --- a/test/source/browser/controllable.ts +++ b/test/source/browser/controllable.ts @@ -273,7 +273,7 @@ abstract class ControllableBase { await this.waitAndClick(`@ui-modal-${type}-${clickBtn}`); } - public waitAndClick = async (selector: string, { delay = 0.1, timeout = 10000, confirmGone = false, retryErrs = false, sleepWhenDone }: + public waitAndClick = async (selector: string, { delay = 0.1, timeout = TIMEOUT_ELEMENT_APPEAR, confirmGone = false, retryErrs = false, sleepWhenDone }: { delay?: number, timeout?: number, confirmGone?: boolean, retryErrs?: boolean, sleepWhenDone?: number } = {}) => { for (const i of [1, 2, 3]) { this.log(`wait_and_click(i${i}):1:${selector}`); diff --git a/test/source/tests/page-recipe/setup-page-recipe.ts b/test/source/tests/page-recipe/setup-page-recipe.ts index ba114aef92f..c381001195c 100644 --- a/test/source/tests/page-recipe/setup-page-recipe.ts +++ b/test/source/tests/page-recipe/setup-page-recipe.ts @@ -108,9 +108,9 @@ export class SetupPageRecipe extends PageRecipe { ) { if (!noPrvCreateOrgRule) { if (usedPgpBefore) { - await settingsPage.waitAndClick('@action-step0foundkey-choose-manual-enter', { timeout: 30000, retryErrs: true }); + await settingsPage.waitAndClick('@action-step0foundkey-choose-manual-enter', { timeout: 30, retryErrs: true }); } else { - await settingsPage.waitAndClick('@action-step1easyormanual-choose-manual-enter', { timeout: 30000, retryErrs: true }); + await settingsPage.waitAndClick('@action-step1easyormanual-choose-manual-enter', { timeout: 30, retryErrs: true }); } } key = key || Config.key(keyTitle); @@ -186,7 +186,7 @@ export class SetupPageRecipe extends PageRecipe { } await settingsPage.waitAndClick('@input-step2bmanualenter-save', { delay: 1 }); if (fixKey) { - await settingsPage.waitAll('@input-compatibility-fix-expire-years', { timeout: 30000 }); + await settingsPage.waitAll('@input-compatibility-fix-expire-years', { timeout: 30 }); await settingsPage.selectOption('@input-compatibility-fix-expire-years', '1'); await settingsPage.waitAndClick('@action-fix-and-import-key'); } @@ -284,9 +284,9 @@ export class SetupPageRecipe extends PageRecipe { private static createBegin = async (settingsPage: ControllablePage, keyTitle: string, { key, usedPgpBefore = false }: { key?: { passphrase: string }, usedPgpBefore?: boolean } = {}) => { const k = key || Config.key(keyTitle); if (usedPgpBefore) { - await settingsPage.waitAndClick('@action-step0foundkey-choose-manual-create', { timeout: 30000 }); + await settingsPage.waitAndClick('@action-step0foundkey-choose-manual-create', { timeout: 30 }); } else { - await settingsPage.waitAndClick('@action-step1easyormanual-choose-manual-create', { timeout: 30000, retryErrs: true }); + await settingsPage.waitAndClick('@action-step1easyormanual-choose-manual-create', { timeout: 30, retryErrs: true }); } await settingsPage.waitAndType('@input-step2bmanualcreate-passphrase-1', k.passphrase); await settingsPage.waitAndType('@input-step2bmanualcreate-passphrase-2', k.passphrase); From 15acf39eb1eca1b862a978fed2eeafd49a9f6fcf Mon Sep 17 00:00:00 2001 From: Limon Monte Date: Tue, 9 Nov 2021 10:37:11 +0200 Subject: [PATCH 22/22] let composeBox: Controllable | undefined --- test/source/tests/gmail.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index 4c63c8b2a62..30140b1ddb3 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -3,6 +3,7 @@ import * as ava from 'ava'; import { BrowserHandle, ControllablePage } from './../browser'; +import { Controllable } from './../browser/controllable'; import { TestVariant, Util } from './../util'; import { AvaContext } from './tooling'; import { BrowserRecipe } from './tooling/browser-recipe'; @@ -43,7 +44,7 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }; const createSecureDraft = async (t: AvaContext, browser: BrowserHandle, gmailPage: ControllablePage, content: string, params: { offline: boolean } = { offline: false }) => { - let composeBox; + let composeBox: Controllable | undefined; if (params.offline) { // TODO(@limonte): for some reason iframe is able to save the draft to the cloud even // after gmailPage.page.setOfflineMode(true) is called. Probably, the puppeteer issue, revisit.