From 8cbadf16a7c13e20d4db85d0a70bb9e394d4d128 Mon Sep 17 00:00:00 2001 From: KobeNguyenT <7845001+kobenguyent@users.noreply.github.com> Date: Wed, 23 Aug 2023 16:14:27 +0200 Subject: [PATCH] fix(playwright): userDataDir and locale config options show error this.browser.contexts is not a function (#3814) * fix: #2887 * fix: improve code * fix: error * fix: error with _session * fix: stabilize test * fix: session issue * fix: session error * fix: session issue --- docs/helpers/Playwright.md | 1 + lib/helper/Playwright.js | 56 ++++++++++++++++++++++++++------------ 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/docs/helpers/Playwright.md b/docs/helpers/Playwright.md index 4a246ffc0..038c8886d 100644 --- a/docs/helpers/Playwright.md +++ b/docs/helpers/Playwright.md @@ -165,6 +165,7 @@ Traces will be saved to `output/trace` url: "http://localhost", show: true // headless mode not supported for extensions chromium: { + // Note: due to this would launch persistent context, so to avoid the error when running tests with run-workers a timestamp would be appended to the defined folder name. For instance: playwright-tmp_1692715649511 userDataDir: '/tmp/playwright-tmp', // necessary to launch the browser in normal mode instead of incognito, args: [ `--disable-extensions-except=${pathToExtension}`, diff --git a/lib/helper/Playwright.js b/lib/helper/Playwright.js index 8db23fc70..87b7803e7 100644 --- a/lib/helper/Playwright.js +++ b/lib/helper/Playwright.js @@ -208,6 +208,7 @@ const config = {}; * url: "http://localhost", * show: true // headless mode not supported for extensions * chromium: { + * // Note: due to this would launch persistent context, so to avoid the error when running tests with run-workers a timestamp would be appended to the defined folder name. For instance: playwright-tmp_1692715649511 * userDataDir: '/tmp/playwright-tmp', // necessary to launch the browser in normal mode instead of incognito, * args: [ * `--disable-extensions-except=${pathToExtension}`, @@ -396,7 +397,7 @@ class Playwright extends Helper { } this.isRemoteBrowser = !!this.playwrightOptions.browserWSEndpoint; this.isElectron = this.options.browser === 'electron'; - this.userDataDir = this.playwrightOptions.userDataDir; + this.userDataDir = this.playwrightOptions.userDataDir ? `${this.playwrightOptions.userDataDir}_${Date.now().toString()}` : undefined; this.isCDPConnection = this.playwrightOptions.cdpConnection; popupStore.defaultAction = this.options.defaultPopupAction; } @@ -469,7 +470,7 @@ class Playwright extends Helper { this.isAuthenticated = false; if (this.isElectron) { this.browserContext = this.browser.context(); - } else if (this.userDataDir) { + } else if (this.playwrightOptions.userDataDir) { this.browserContext = this.browser; } else { const contextOptions = { @@ -495,8 +496,17 @@ class Playwright extends Helper { if (this.isElectron) { mainPage = await this.browser.firstWindow(); } else { - const existingPages = await this.browserContext.pages(); - mainPage = existingPages[0] || await this.browserContext.newPage(); + try { + const existingPages = await this.browserContext.pages(); + mainPage = existingPages[0] || await this.browserContext.newPage(); + } catch (e) { + if (this.playwrightOptions.userDataDir) { + this.browser = await playwright[this.options.browser].launchPersistentContext(this.userDataDir, this.playwrightOptions); + this.browserContext = this.browser; + const existingPages = await this.browserContext.pages(); + mainPage = existingPages[0]; + } + } } await targetCreatedHandler.call(this, mainPage); @@ -527,13 +537,15 @@ class Playwright extends Helper { // close other sessions try { - const contexts = await this.browser.contexts(); - const currentContext = contexts[0]; - if (currentContext && (this.options.keepCookies || this.options.keepBrowserState)) { - this.storageState = await currentContext.storageState(); - } + if ((await this.browser)._type === 'Browser') { + const contexts = await this.browser.contexts(); + const currentContext = contexts[0]; + if (currentContext && (this.options.keepCookies || this.options.keepBrowserState)) { + this.storageState = await currentContext.storageState(); + } - await Promise.all(contexts.map(c => c.close())); + await Promise.all(contexts.map(c => c.close())); + } } catch (e) { console.log(e); } @@ -563,8 +575,16 @@ class Playwright extends Helper { browserContext = browser.context(); page = await browser.firstWindow(); } else { - browserContext = await this.browser.newContext(Object.assign(this.options, config)); - page = await browserContext.newPage(); + try { + browserContext = await this.browser.newContext(Object.assign(this.options, config)); + page = await browserContext.newPage(); + } catch (e) { + if (this.playwrightOptions.userDataDir) { + browserContext = await playwright[this.options.browser].launchPersistentContext(`${this.userDataDir}_${this.activeSessionName}`, this.playwrightOptions); + this.browser = browserContext; + page = await browserContext.pages()[0]; + } + } } if (this.options.trace) await browserContext.tracing.start({ screenshots: true, snapshots: true }); @@ -577,10 +597,12 @@ class Playwright extends Helper { // is closed by _after }, loadVars: async (context) => { - this.browserContext = context; - const existingPages = await context.pages(); - this.sessionPages[this.activeSessionName] = existingPages[0]; - return this._setPage(this.sessionPages[this.activeSessionName]); + if (context) { + this.browserContext = context; + const existingPages = await context.pages(); + this.sessionPages[this.activeSessionName] = existingPages[0]; + return this._setPage(this.sessionPages[this.activeSessionName]); + } }, restoreVars: async (session) => { this.withinLocator = null; @@ -771,7 +793,7 @@ class Playwright extends Helper { } throw err; } - } else if (this.userDataDir) { + } else if (this.playwrightOptions.userDataDir) { this.browser = await playwright[this.options.browser].launchPersistentContext(this.userDataDir, this.playwrightOptions); } else { this.browser = await playwright[this.options.browser].launch(this.playwrightOptions);