From 870919611adf4418db83443eeff96642f59ad220 Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Wed, 15 Dec 2021 17:27:21 +0530 Subject: [PATCH 01/20] Fix timeout calculation in page --- package.json | 2 +- pageinit.back | 82 ++++++++++ .../PlayWrightExecutor.ts | 144 ++++++------------ 3 files changed, 131 insertions(+), 97 deletions(-) create mode 100644 pageinit.back diff --git a/package.json b/package.json index dcda265..8cf5e97 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "storywright", "description": "Storybook setup.", "license": "MIT", - "version": "0.0.7", + "version": "0.0.8", "main": "lib/index.js", "module": "lib/index.js", "typings": "lib/index.d.ts", diff --git a/pageinit.back b/pageinit.back new file mode 100644 index 0000000..847ffe8 --- /dev/null +++ b/pageinit.back @@ -0,0 +1,82 @@ +//Just for backup to refer later + +this.page.addInitScript(`{ + const _promiseConstructor = window.Promise.constructor; + const _timeoutIds = new Set(); + const _setTimeout = window.setTimeout; + const _clearTimeout = window.clearTimeout; + + new MutationObserver(() => { + window.__pwBusy__("dom++"); + requestAnimationFrame(() => { window.__pwBusy__("dom--"); }); + }).observe(document, { attributes: true, childList: true, subtree: true }); + + // Patch Promise constructor + window.Promise.constructor = async (resolve, reject) => { + window.__pwBusy__("promises++"); + + const res = resolve && (async () => { + let val; + try { + val = await resolve(); + } catch(err) { + throw err; + } finally { + window.__pwBusy__("promises--"); + } + return val; + }); + + const rej = reject && (async () => { + let val; + try { + val = await reject(); + } catch(err) { + throw err; + } finally { + window.__pwBusy__("promises--"); + } + return val; + }); + + return _promiseConstructor.call(this, res, rej); + }; + + // Path window.clearTimeout + window.clearTimeout = (id) => { + _clearTimeout(id); + if (_timeoutIds.has(id)) { + _timeoutIds.delete(id); + window.__pwBusy__("timeouts--"); + } + }; + // Patch window.setTimeout in the near future + window.setTimeout = (...args) => { + const ms = args[1]; + const isInNearFuture = ms < 1000 * 5; + if (isInNearFuture) { + window.__pwBusy__("timeouts++"); + const fn = args[0]; + if (typeof(fn) === "function") { + args[0] = () => { + try { + fn(); + } catch(err) { + } finally { + window.__pwBusy__("timeouts--"); + } + }; + } else { + args[0] = "try{" + args[0] + "; }catch(err){};window.__pwBusy__('timeouts--');"; + } + } + + const timeoutId = _setTimeout.apply(this, args); + + if (isInNearFuture) { + _timeoutIds.add(timeoutId); + } + + return timeoutId; + }; + }`); \ No newline at end of file diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index 621e30d..aac256f 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -1,5 +1,5 @@ import * as fs from "fs"; -import { Page, Frame } from "playwright"; +import { Page } from "playwright"; import { sep } from "path"; /** * Class containing playwright exposed functions. @@ -26,14 +26,6 @@ export class PlayWrightExecutor { mutatedDom: 0, }; - this.page.on("framenavigated", (frame: Frame) => { - if (!frame.parentFrame()) { - busy.pendingPromises = 0; - busy.pendingTimeouts = 0; - busy.networkOrCpu = 0; - busy.mutatedDom = 0; - } - }); await this.page.exposeFunction("__pwBusy__", (key: string) => { if (key === "promises++") { @@ -51,85 +43,28 @@ export class PlayWrightExecutor { } }); - this.page.addInitScript(`{ - const _promiseConstructor = window.Promise.constructor; - const _timeoutIds = new Set(); - const _setTimeout = window.setTimeout; - const _clearTimeout = window.clearTimeout; - - new MutationObserver(() => { - window.__pwBusy__("dom++"); - requestAnimationFrame(() => { window.__pwBusy__("dom--"); }); - }).observe(document, { attributes: true, childList: true, subtree: true }); - - // Patch Promise constructor - window.Promise.constructor = async (resolve, reject) => { - window.__pwBusy__("promises++"); - - const res = resolve && (async () => { - let val; - try { - val = await resolve(); - } catch(err) { - throw err; - } finally { - window.__pwBusy__("promises--"); - } - return val; - }); - - const rej = reject && (async () => { - let val; - try { - val = await reject(); - } catch(err) { - throw err; - } finally { - window.__pwBusy__("promises--"); - } - return val; - }); - - return _promiseConstructor.call(this, res, rej); - }; - - // Path window.clearTimeout - window.clearTimeout = (id) => { - _clearTimeout(id); - if (_timeoutIds.has(id)) { - _timeoutIds.delete(id); - window.__pwBusy__("timeouts--"); - } - }; - // Patch window.setTimeout in the near future - window.setTimeout = (...args) => { - const ms = args[1]; - const isInNearFuture = ms < 1000 * 5; - if (isInNearFuture) { - window.__pwBusy__("timeouts++"); - const fn = args[0]; - if (typeof(fn) === "function") { - args[0] = () => { - try { - fn(); - } catch(err) { - } finally { - window.__pwBusy__("timeouts--"); - } - }; - } else { - args[0] = "try{" + args[0] + "; }catch(err){};window.__pwBusy__('timeouts--');"; - } - } - - const timeoutId = _setTimeout.apply(this, args); - - if (isInNearFuture) { - _timeoutIds.add(timeoutId); - } - - return timeoutId; - }; + await this.page.addInitScript(`{ + const _setTimeout = window.setTimeout; + const _clearTimeout = window.clearTimeout; + + window.clearTimeout = (id) => { + _clearTimeout(id); + window.__pwBusy__("timeouts--"); + } + + window.setTimeout = function(func, delay, params) { + window.__pwBusy__("timeouts++"); + const timeoutId = _setTimeout(window.timeoutCallback, delay, [func, params]); + return timeoutId; + } + + window.timeoutCallback = function(funcAndParams) { + let func = funcAndParams[0]; + let params = funcAndParams[1]; + window.__pwBusy__("timeouts--"); + func(params); + } + }`); return async (): Promise => { @@ -141,28 +76,45 @@ export class PlayWrightExecutor { })`); busy.networkOrCpu = Math.max(0, Date.now() - now - 3); // Allow a short delay due to node/browser bridge + //Temporarity remove network and other checks const isBusy = - busy.networkOrCpu + - busy.mutatedDom + - busy.pendingPromises + busy.pendingTimeouts > 0; - + + // Busy pending timeout is not expected so log it. + if(busy.pendingTimeouts<0) + { + console.log(`ERRR : Pending timeouts less than 0 ${busy.pendingTimeouts}`); + } return isBusy; }; }; - private async checkIfPageIsBusy() { + private async checkIfPageIsBusy(screenshotPath:string) { // Check if 2 consecutive frames are equal. // For now removing checkispagebusy as that is causing issues. Will investigate and add that later. let prevBuf:Buffer; let buf:Buffer = await this.page.screenshot(); const timeout = Date.now() + 4000; // WHATEVER REASONABLE TIME WE DECIDE + let isBuffEqual: boolean; + let isBusy: boolean; do { prevBuf = buf; await this.page.waitForTimeout(100); buf = await this.page.screenshot(); - } while ( !(buf.equals(prevBuf)) && Date.now() < timeout); + isBuffEqual = buf.equals(prevBuf); + isBusy = await this.isPageBusy(); + } while ((!isBuffEqual || isBusy) && Date.now() < timeout); + + // In case the above loop existed due to timeout them log the reason for debugging purpose. + if(!isBuffEqual) + { + console.log(`E222 : Buffers not equal for ${this.page.url()} Path = ${screenshotPath}`) + } + if(isBusy) + { + console.log(`E2223 : Page busy for ${this.page.url()} Path = ${screenshotPath}`) + } } public async exposeFunctions() { @@ -272,7 +224,7 @@ export class PlayWrightExecutor { private makeScreenshot = async (testName?: string) => { try { let screenshotPath = this.getScreenshotPath(testName); - await this.checkIfPageIsBusy(); + await this.checkIfPageIsBusy(screenshotPath); await this.page.screenshot({ path: screenshotPath, }); @@ -289,7 +241,7 @@ export class PlayWrightExecutor { if (await element.isVisible()) { let screenshotPath = this.getScreenshotPath(testName); - await this.checkIfPageIsBusy(); + await this.checkIfPageIsBusy(screenshotPath); await element.screenshot({ path: screenshotPath, }); From 0b3a88a895c951fbc41e64278901c8deac94e647 Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Wed, 15 Dec 2021 21:24:27 +0530 Subject: [PATCH 02/20] fix timeout tracking --- package.json | 2 +- .../PlayWrightExecutor.ts | 37 +++++++++++-------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 8cf5e97..2acd7a8 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "storywright", "description": "Storybook setup.", "license": "MIT", - "version": "0.0.8", + "version": "0.0.9", "main": "lib/index.js", "module": "lib/index.js", "typings": "lib/index.d.ts", diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index aac256f..279442c 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -26,16 +26,22 @@ export class PlayWrightExecutor { mutatedDom: 0, }; + // Mainting set here instead in page initscript becuase its easy to debug and view logs here + const timeoutIdSet = new Set(); - await this.page.exposeFunction("__pwBusy__", (key: string) => { + await this.page.exposeFunction("__pwBusy__", (key: string, timeoutId: number) => { if (key === "promises++") { busy.pendingPromises++; } else if (key === "promises--") { busy.pendingPromises--; } else if (key === "timeouts++") { + timeoutIdSet.add(timeoutId); busy.pendingTimeouts++; } else if (key === "timeouts--") { - busy.pendingTimeouts--; + if (timeoutIdSet.has(timeoutId)) { + timeoutIdSet.delete(timeoutId); + busy.pendingTimeouts--; + } } else if (key === "dom++") { busy.mutatedDom++; } else if (key === "dom--") { @@ -47,24 +53,23 @@ export class PlayWrightExecutor { const _setTimeout = window.setTimeout; const _clearTimeout = window.clearTimeout; - window.clearTimeout = (id) => { - _clearTimeout(id); - window.__pwBusy__("timeouts--"); + window.clearTimeout = (timeoutId) => { + _clearTimeout(timeoutId); + window.__pwBusy__("timeouts--",timeoutId); } - window.setTimeout = function(func, delay, params) { - window.__pwBusy__("timeouts++"); - const timeoutId = _setTimeout(window.timeoutCallback, delay, [func, params]); + window.setTimeout = function(fn, delay, params) { + alert(params); + + var timeoutId = _setTimeout(function() { + window.__pwBusy__("timeouts--",timeoutId); + fn && fn(params); + }, delay); + + window.__pwBusy__("timeouts++",timeoutId); return timeoutId; } - - window.timeoutCallback = function(funcAndParams) { - let func = funcAndParams[0]; - let params = funcAndParams[1]; - window.__pwBusy__("timeouts--"); - func(params); - } - + }`); return async (): Promise => { From c1564813448ac9d5c0ba02e26dc2f71bb4ff6e7a Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Wed, 15 Dec 2021 21:44:02 +0530 Subject: [PATCH 03/20] Fix code review comment --- src/StoryWrightProcessor/PlayWrightExecutor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index bfbc0ba..f3d09db 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -60,8 +60,8 @@ export class PlayWrightExecutor { window.setTimeout = function(fn, delay, params) { var timeoutId = _setTimeout(function() { + fn && fn(params); window.__pwBusy__("timeouts--",timeoutId); - fn && fn(params); }, delay); window.__pwBusy__("timeouts++",timeoutId); From 2428b0c47bd0b6e25f937fce2a1da65e5c60c16b Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Wed, 15 Dec 2021 22:23:14 +0530 Subject: [PATCH 04/20] Reduce timeout for long timeouts --- src/StoryWrightProcessor/PlayWrightExecutor.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index f3d09db..84ec060 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -59,6 +59,11 @@ export class PlayWrightExecutor { } window.setTimeout = function(fn, delay, params) { + // If there too much delay then we reduce it. + if(delay>3000) + { + delay=3000; + } var timeoutId = _setTimeout(function() { fn && fn(params); window.__pwBusy__("timeouts--",timeoutId); @@ -98,7 +103,7 @@ export class PlayWrightExecutor { // For now removing checkispagebusy as that is causing issues. Will investigate and add that later. let prevBuf:Buffer; let buf:Buffer = await this.page.screenshot(); - const timeout = Date.now() + 4000; // WHATEVER REASONABLE TIME WE DECIDE + const timeout = Date.now() + 5000; // WHATEVER REASONABLE TIME WE DECIDE let isBuffEqual: boolean; let isBusy: boolean; do { From 09061fc36741129913ba353776a15420795eed5b Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Wed, 15 Dec 2021 22:29:13 +0530 Subject: [PATCH 05/20] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2acd7a8..461ffa1 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "storywright", "description": "Storybook setup.", "license": "MIT", - "version": "0.0.9", + "version": "0.0.10", "main": "lib/index.js", "module": "lib/index.js", "typings": "lib/index.d.ts", From 53cad8d2c964290351b867986c1ca9f77fbe7e83 Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Thu, 16 Dec 2021 11:37:47 +0530 Subject: [PATCH 06/20] fix flakiness by adjusting timeouts --- package.json | 2 +- src/StoryWrightProcessor/PlayWrightExecutor.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 461ffa1..a7ef9ee 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "storywright", "description": "Storybook setup.", "license": "MIT", - "version": "0.0.10", + "version": "0.0.11", "main": "lib/index.js", "module": "lib/index.js", "typings": "lib/index.d.ts", diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index 84ec060..fdc2b49 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -60,9 +60,9 @@ export class PlayWrightExecutor { window.setTimeout = function(fn, delay, params) { // If there too much delay then we reduce it. - if(delay>3000) + if(delay>7000) { - delay=3000; + return; } var timeoutId = _setTimeout(function() { fn && fn(params); @@ -103,12 +103,12 @@ export class PlayWrightExecutor { // For now removing checkispagebusy as that is causing issues. Will investigate and add that later. let prevBuf:Buffer; let buf:Buffer = await this.page.screenshot(); - const timeout = Date.now() + 5000; // WHATEVER REASONABLE TIME WE DECIDE + const timeout = Date.now() + 8000; // WHATEVER REASONABLE TIME WE DECIDE let isBuffEqual: boolean; let isBusy: boolean; do { prevBuf = buf; - await this.page.waitForTimeout(100); + await this.page.waitForTimeout(300); buf = await this.page.screenshot(); isBuffEqual = buf.equals(prevBuf); isBusy = await this.isPageBusy(); From ca15f20f17bc34e813aff2491046d1bb2ccc2c1e Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Thu, 16 Dec 2021 11:39:13 +0530 Subject: [PATCH 07/20] fix flakiness by adjusting timeouts --- src/StoryWrightProcessor/PlayWrightExecutor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index fdc2b49..654cb40 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -59,7 +59,7 @@ export class PlayWrightExecutor { } window.setTimeout = function(fn, delay, params) { - // If there too much delay then we reduce it. + // If there too much delay then we ignore it. if(delay>7000) { return; From 769cdd9590f81023c126e1966f11fc9dfaca1a6e Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Thu, 16 Dec 2021 11:59:09 +0530 Subject: [PATCH 08/20] fix flakiness by adjusting timeouts --- src/StoryWrightProcessor/PlayWrightExecutor.ts | 2 +- src/StoryWrightProcessor/StoryWrightProcessor.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index 654cb40..292d6f0 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -59,7 +59,7 @@ export class PlayWrightExecutor { } window.setTimeout = function(fn, delay, params) { - // If there too much delay then we ignore it. + // If there too much delay then we ignore it as our process will close even before that. if(delay>7000) { return; diff --git a/src/StoryWrightProcessor/StoryWrightProcessor.ts b/src/StoryWrightProcessor/StoryWrightProcessor.ts index e304b90..102b871 100644 --- a/src/StoryWrightProcessor/StoryWrightProcessor.ts +++ b/src/StoryWrightProcessor/StoryWrightProcessor.ts @@ -131,8 +131,8 @@ export class StoryWrightProcessor { console.log(`story:${++storyIndex}/${stories.length} ${id}`); - // Wait for close event to be fired from steps. Default timeout is 30 seconds. - await page.waitForEvent("close", { timeout: 60000 }); + // Wait for close event to be fired from steps. Wait for 1 min 30 seconds. + await page.waitForEvent("close", { timeout: 90000 }); } } catch (err) { console.log( From 93e391701656d2a06d4c2e457767e1fd66e0c06c Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Thu, 16 Dec 2021 12:05:01 +0530 Subject: [PATCH 09/20] fix flakiness by adjusting timeouts --- src/StoryWrightProcessor/PlayWrightExecutor.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index 292d6f0..e671632 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -59,20 +59,16 @@ export class PlayWrightExecutor { } window.setTimeout = function(fn, delay, params) { - // If there too much delay then we ignore it as our process will close even before that. - if(delay>7000) - { - return; - } + const isInNearFuture = delay < 1000 * 7; var timeoutId = _setTimeout(function() { - fn && fn(params); window.__pwBusy__("timeouts--",timeoutId); + fn && fn(params); }, delay); - - window.__pwBusy__("timeouts++",timeoutId); + if (isInNearFuture) { + window.__pwBusy__("timeouts++",timeoutId); + } return timeoutId; } - }`); return async (): Promise => { From 69678cdaa7041f7688191538cb873f96bf86e7a0 Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Thu, 16 Dec 2021 13:59:32 +0530 Subject: [PATCH 10/20] Fix code review comment --- src/StoryWrightProcessor/PlayWrightExecutor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index e671632..28831c4 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -61,8 +61,8 @@ export class PlayWrightExecutor { window.setTimeout = function(fn, delay, params) { const isInNearFuture = delay < 1000 * 7; var timeoutId = _setTimeout(function() { + fn && fn(params); window.__pwBusy__("timeouts--",timeoutId); - fn && fn(params); }, delay); if (isInNearFuture) { window.__pwBusy__("timeouts++",timeoutId); From 1ea36b02be3cf3dfaacd96955498566151e4a8cf Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Thu, 16 Dec 2021 14:08:10 +0530 Subject: [PATCH 11/20] add await --- src/StoryWrightProcessor/StoryWrightProcessor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StoryWrightProcessor/StoryWrightProcessor.ts b/src/StoryWrightProcessor/StoryWrightProcessor.ts index 102b871..8f6d80b 100644 --- a/src/StoryWrightProcessor/StoryWrightProcessor.ts +++ b/src/StoryWrightProcessor/StoryWrightProcessor.ts @@ -79,7 +79,7 @@ export class StoryWrightProcessor { }); // Add basic CSS normalization - page.addInitScript(() => { + await page.addInitScript(() => { document.addEventListener("DOMContentLoaded", () => { const style = document.createElement("style"); style.textContent = ` From 5d737c867a8e5070de72fef16040c28415d45224 Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Thu, 16 Dec 2021 17:09:06 +0530 Subject: [PATCH 12/20] log cores information --- .vscode/launch.json | 22 ++++++++++++++++++++++ src/main.ts | 3 +++ 2 files changed, 25 insertions(+) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..52b90a8 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,22 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "pwa-node", + "request": "launch", + "name": "Launch Program", + "skipFiles": [ + "/**" + ], + "cwd": "C:\\GIT\\vrt", + "program": "C:\\GIT\\storywright\\bin\\storywright.js", + "args": ["--concurrency","1","--browsers","chromium","--destpath","chromium-baseline"], + "outFiles": [ + "${workspaceFolder}/lib/**/*.js" + ] + } + ] +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 331e5bc..13e345d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,6 +4,8 @@ import { BrowserName } from "./StoryWrightProcessor/Constants"; import { StoryWrightOptions } from "./StoryWrightProcessor/StoryWrightOptions"; import { StoryWrightProcessor } from "./StoryWrightProcessor/StoryWrightProcessor"; import { resolve } from "path"; +import {cpus} from "os"; + const args = argv .usage("Usage: $0 [options]") .help("h") @@ -90,6 +92,7 @@ console.log(`Screenshot destination path = ${args.destpath}`); console.log(`Browsers = ${args.browsers}`); console.log(`Headless = ${args.headless}`); console.log(`Concurrency = ${args.concurrency}`); +console.log(`Cores available on system = ${cpus().length}`); console.log(`SkipSteps = ${args.skipSteps}`); console.log( `================ Starting story right execution =================` From 6b2d5fbd9c8ee85934cf126c9d2d69e9b1a67211 Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Thu, 16 Dec 2021 18:08:57 +0530 Subject: [PATCH 13/20] Delete launch.json --- .vscode/launch.json | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 52b90a8..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "pwa-node", - "request": "launch", - "name": "Launch Program", - "skipFiles": [ - "/**" - ], - "cwd": "C:\\GIT\\vrt", - "program": "C:\\GIT\\storywright\\bin\\storywright.js", - "args": ["--concurrency","1","--browsers","chromium","--destpath","chromium-baseline"], - "outFiles": [ - "${workspaceFolder}/lib/**/*.js" - ] - } - ] -} \ No newline at end of file From bb8139f5e2c49722795cf4301bc0711b929068f3 Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Thu, 16 Dec 2021 22:51:50 +0530 Subject: [PATCH 14/20] Fix previos code review comment --- package.json | 2 +- src/StoryWrightProcessor/PlayWrightExecutor.ts | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index a7ef9ee..ec28dee 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "storywright", "description": "Storybook setup.", "license": "MIT", - "version": "0.0.11", + "version": "0.0.12", "main": "lib/index.js", "module": "lib/index.js", "typings": "lib/index.d.ts", diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index 28831c4..12d34a0 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -61,8 +61,12 @@ export class PlayWrightExecutor { window.setTimeout = function(fn, delay, params) { const isInNearFuture = delay < 1000 * 7; var timeoutId = _setTimeout(function() { - fn && fn(params); - window.__pwBusy__("timeouts--",timeoutId); + try { + fn && fn(params); + } + finally { + window.__pwBusy__("timeouts--",timeoutId); + } }, delay); if (isInNearFuture) { window.__pwBusy__("timeouts++",timeoutId); From a225e0549c77081ee2e29a556dba379187424dd5 Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Fri, 17 Dec 2021 10:57:20 +0530 Subject: [PATCH 15/20] fix keypress --- src/StoryWright/BrowserExecutor.ts | 34 ++++++++----- .../PlayWrightExecutor.ts | 51 +++++++++---------- 2 files changed, 44 insertions(+), 41 deletions(-) diff --git a/src/StoryWright/BrowserExecutor.ts b/src/StoryWright/BrowserExecutor.ts index 8c50248..d7e0805 100644 --- a/src/StoryWright/BrowserExecutor.ts +++ b/src/StoryWright/BrowserExecutor.ts @@ -51,22 +51,28 @@ export class BrowserExecutor { break; } case StepType.SendKeys: { - let keyFound = false; - - Object.keys(Keys).map((key) => { - if (Keys[key] == step.keys) { - keyFound = true; - } - }); + // No key value mean focus. if (step.keys === "") { await TestExecutorActions.focus(step.locator.value); - } else if (!keyFound) { - await TestExecutorActions.setElementText( - step.locator.value, - step.keys - ); - } else { - await TestExecutorActions.pressKey(step.locator.value, step.keys); + } + else { + let keyToSend; + for (const key of Object.keys(Keys)) { + if (Keys[key] == step.keys || key == step.keys) { + keyToSend = Keys[key]; + break; + } + } + // If no key found means set text in textbox. + if (!keyToSend) { + await TestExecutorActions.setElementText( + step.locator.value, + step.keys + ); + } + else { + await TestExecutorActions.pressKey(step.locator.value, keyToSend); + } } break; } diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index 12d34a0..0cb9e3c 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -25,10 +25,10 @@ export class PlayWrightExecutor { networkOrCpu: 0, mutatedDom: 0, }; - + // Mainting set here instead in page initscript becuase its easy to debug and view logs here const timeoutIdSet = new Set(); - + await this.page.exposeFunction("__pwBusy__", (key: string, timeoutId: number) => { if (key === "promises++") { busy.pendingPromises++; @@ -48,7 +48,7 @@ export class PlayWrightExecutor { busy.mutatedDom--; } }); - + await this.page.addInitScript(`{ const _setTimeout = window.setTimeout; const _clearTimeout = window.clearTimeout; @@ -74,7 +74,7 @@ export class PlayWrightExecutor { return timeoutId; } }`); - + return async (): Promise => { // Check if the network or CPU are idle const now = Date.now(); @@ -83,26 +83,25 @@ export class PlayWrightExecutor { window.requestIdleCallback(() => { resolve(); }); })`); busy.networkOrCpu = Math.max(0, Date.now() - now - 3); // Allow a short delay due to node/browser bridge - + //Temporarity remove network and other checks const isBusy = - busy.pendingTimeouts > + busy.pendingTimeouts > 0; // Busy pending timeout is not expected so log it. - if(busy.pendingTimeouts<0) - { + if (busy.pendingTimeouts < 0) { console.log(`ERRR : Pending timeouts less than 0 ${busy.pendingTimeouts}`); } return isBusy; }; }; - private async checkIfPageIsBusy(screenshotPath:string) { + private async checkIfPageIsBusy(screenshotPath: string) { // Check if 2 consecutive frames are equal. // For now removing checkispagebusy as that is causing issues. Will investigate and add that later. - let prevBuf:Buffer; - let buf:Buffer = await this.page.screenshot(); + let prevBuf: Buffer; + let buf: Buffer = await this.page.screenshot(); const timeout = Date.now() + 8000; // WHATEVER REASONABLE TIME WE DECIDE let isBuffEqual: boolean; let isBusy: boolean; @@ -115,18 +114,16 @@ export class PlayWrightExecutor { } while ((!isBuffEqual || isBusy) && Date.now() < timeout); // In case the above loop existed due to timeout them log the reason for debugging purpose. - if(!isBuffEqual) - { + if (!isBuffEqual) { console.log(`E222 : Buffers not equal for ${this.page.url()} Path = ${screenshotPath}`) } - if(isBusy) - { + if (isBusy) { console.log(`E2223 : Page busy for ${this.page.url()} Path = ${screenshotPath}`) } - } + } public async exposeFunctions() { - this.isPageBusy = await this.getIsPageBusyMethod(); + this.isPageBusy = await this.getIsPageBusyMethod(); await this.page.exposeFunction("makeScreenshot", this.makeScreenshot); await this.page.exposeFunction("click", this.click); await this.page.exposeFunction("hover", this.hover); @@ -197,7 +194,7 @@ export class PlayWrightExecutor { private pressKey = async (selector: string, key: string) => { try { selector = this.curateSelector(selector); - await this.page.press(selector, key); + await this.page.keyboard.press(key); } catch (err) { console.error("ERROR: pressKey: ", err.message); throw err; @@ -329,32 +326,32 @@ export class PlayWrightExecutor { } // INFO: Removes non-ASCII characters - private removeNonASCIICharacters(name: string){ - return name.replace(/[^\x00-\x7F]/g,""); + private removeNonASCIICharacters(name: string) { + return name.replace(/[^\x00-\x7F]/g, ""); } /* This will insert double quotes around selector string, if missing. Eg: buttonbutton[data-id=ex123][attr=ex432] will be changed to button[data-id="ex123"][attr="ex432"] */ - private curateSelector(selector: string){ + private curateSelector(selector: string) { //No need to check if selector doesn't contain equals to (=) - if(selector.indexOf("=") == -1){ + if (selector.indexOf("=") == -1) { return selector; } let newSelector = ""; - newSelector = selector.substring(0, selector.indexOf("=")+1); + newSelector = selector.substring(0, selector.indexOf("=") + 1); //Loop through all attributes - while(selector.indexOf("[") > -1 && selector.indexOf("=") > -1){ + while (selector.indexOf("[") > -1 && selector.indexOf("=") > -1) { /* Pulls out chars b/w equals to (=) and closing square bracket (]) Eg: button[data-id=ex123] will give "ex123" to temp */ let temp = selector.substring(selector.indexOf("=") + 1, selector.indexOf("]")); // Check if temp is not surrounded by either double/single quotes - if(!(temp.charAt(0) == '"' || temp.charAt(0) == '\'')){ + if (!(temp.charAt(0) == '"' || temp.charAt(0) == '\'')) { temp = '"' + temp + '"'; } @@ -362,9 +359,9 @@ export class PlayWrightExecutor { // Move to the next chunk to curate // Eg: If buttonbutton[data-id=ex123][attr=ex432] then move selector to [attr=432] - selector = selector.substring(selector.indexOf("]")+1, selector.length); + selector = selector.substring(selector.indexOf("]") + 1, selector.length); } - if(selector.length > 0){ + if (selector.length > 0) { newSelector += selector; } From 24252b35869945a599fabd81ad71b9fe0e3bc1a6 Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Fri, 17 Dec 2021 10:58:00 +0530 Subject: [PATCH 16/20] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ec28dee..ca4580b 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "storywright", "description": "Storybook setup.", "license": "MIT", - "version": "0.0.12", + "version": "0.0.13", "main": "lib/index.js", "module": "lib/index.js", "typings": "lib/index.d.ts", From 3fd9a9f2ca6f2942f08af5d2be232915583fba24 Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Fri, 17 Dec 2021 11:34:17 +0530 Subject: [PATCH 17/20] Fix timeout counter update synchronization --- src/StoryWrightProcessor/PlayWrightExecutor.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index 0cb9e3c..ee738e0 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -55,7 +55,7 @@ export class PlayWrightExecutor { window.clearTimeout = (timeoutId) => { _clearTimeout(timeoutId); - window.__pwBusy__("timeouts--",timeoutId); + await window.__pwBusy__("timeouts--",timeoutId); } window.setTimeout = function(fn, delay, params) { @@ -65,11 +65,11 @@ export class PlayWrightExecutor { fn && fn(params); } finally { - window.__pwBusy__("timeouts--",timeoutId); + await window.__pwBusy__("timeouts--",timeoutId); } }, delay); if (isInNearFuture) { - window.__pwBusy__("timeouts++",timeoutId); + await window.__pwBusy__("timeouts++",timeoutId); } return timeoutId; } From 2fb16cd37d21b65cc3adc5e62ad0db838d17f905 Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Fri, 17 Dec 2021 16:02:18 +0530 Subject: [PATCH 18/20] Code review comment --- src/StoryWrightProcessor/PlayWrightExecutor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index ee738e0..3f1265d 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -53,12 +53,12 @@ export class PlayWrightExecutor { const _setTimeout = window.setTimeout; const _clearTimeout = window.clearTimeout; - window.clearTimeout = (timeoutId) => { + window.clearTimeout = async (timeoutId) => { _clearTimeout(timeoutId); await window.__pwBusy__("timeouts--",timeoutId); } - window.setTimeout = function(fn, delay, params) { + window.setTimeout = async function(fn, delay, params) { const isInNearFuture = delay < 1000 * 7; var timeoutId = _setTimeout(function() { try { From 2a035589f37c70b99d5f48d08148759c76fe9190 Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Fri, 17 Dec 2021 16:09:26 +0530 Subject: [PATCH 19/20] add async to function --- src/StoryWrightProcessor/PlayWrightExecutor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StoryWrightProcessor/PlayWrightExecutor.ts b/src/StoryWrightProcessor/PlayWrightExecutor.ts index 3f1265d..9fcc7f0 100644 --- a/src/StoryWrightProcessor/PlayWrightExecutor.ts +++ b/src/StoryWrightProcessor/PlayWrightExecutor.ts @@ -60,7 +60,7 @@ export class PlayWrightExecutor { window.setTimeout = async function(fn, delay, params) { const isInNearFuture = delay < 1000 * 7; - var timeoutId = _setTimeout(function() { + var timeoutId = _setTimeout(async function() { try { fn && fn(params); } From 9f6f4ecc63d3a43e99bb40aaa3b3144ecdc95d74 Mon Sep 17 00:00:00 2001 From: Sunil Surana Date: Fri, 17 Dec 2021 21:25:08 +0530 Subject: [PATCH 20/20] Updating playwright to latest version Updating playwright to latest version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ca4580b..35570ba 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "types": "lib/index.d.ts", "dependencies": { "@types/react": "^17.0.8", - "playwright": "^1.11.1", + "playwright": "^1.17.1", "react": "^17.0.2", "yargs": "^16.2.0" },