Re-add chromedriver retrying from previous webdriver setup (#6846)
* Re-add previous webdriver setup with falling back to BrowserStack setup * Add missing webdriver imports
This commit is contained in:
parent
8cd7bd1b94
commit
14eef58702
26 changed files with 136 additions and 46 deletions
|
@ -1,6 +1,7 @@
|
|||
/* eslint-env jest */
|
||||
/* global jasmine, webdriver */
|
||||
/* global jasmine */
|
||||
import { join } from 'path'
|
||||
import webdriver from 'next-webdriver'
|
||||
import { readFileSync, writeFileSync } from 'fs'
|
||||
import {
|
||||
nextServer,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-env jest */
|
||||
/* global jasmine, webdriver */
|
||||
/* global jasmine */
|
||||
import { readFileSync, writeFileSync } from 'fs'
|
||||
import webdriver from 'next-webdriver'
|
||||
import { join } from 'path'
|
||||
import {
|
||||
renderViaHTTP,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
|
||||
import webdriver from 'next-webdriver'
|
||||
import { readFileSync, writeFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { check } from 'next-test-utils'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
import webdriver from 'next-webdriver'
|
||||
|
||||
export default (context, render) => {
|
||||
describe('With CSP enabled', () => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
import webdriver from 'next-webdriver'
|
||||
import cheerio from 'cheerio'
|
||||
import { waitFor, check } from 'next-test-utils'
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { join } from 'path'
|
||||
import { check, File, waitFor, getReactErrorOverlayContent, getBrowserBodyText } from 'next-test-utils'
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { readFileSync, writeFileSync, renameSync, existsSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { waitFor, check, getBrowserBodyText } from 'next-test-utils'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
import webdriver from 'next-webdriver'
|
||||
|
||||
export default (context) => {
|
||||
describe('process.env', () => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
import webdriver from 'next-webdriver'
|
||||
|
||||
export default (context) => {
|
||||
describe('Client Navigation 404', () => {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-env jest */
|
||||
/* global jasmine, webdriver */
|
||||
/* global jasmine */
|
||||
import { join } from 'path'
|
||||
import webdriver from 'next-webdriver'
|
||||
import renderingSuite from './rendering'
|
||||
import {
|
||||
waitFor,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
|
||||
import webdriver from 'next-webdriver'
|
||||
import { waitFor } from 'next-test-utils' /* check, File */
|
||||
import { readFileSync, writeFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* eslint-env jest */
|
||||
/* global jasmine, webdriver */
|
||||
/* global jasmine */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { join } from 'path'
|
||||
import getPort from 'get-port'
|
||||
import clone from 'clone'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { check, getBrowserBodyText } from 'next-test-utils'
|
||||
|
||||
export default function (context) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { renderViaHTTP, getBrowserBodyText, check } from 'next-test-utils'
|
||||
import cheerio from 'cheerio'
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* eslint-env jest */
|
||||
/* global jasmine, webdriver */
|
||||
/* global jasmine */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { join, resolve } from 'path'
|
||||
import { existsSync } from 'fs'
|
||||
import AbortController from 'abort-controller'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { readFileSync, writeFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { waitFor } from 'next-test-utils'
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* eslint-env jest */
|
||||
/* global jasmine, webdriver */
|
||||
/* global jasmine */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { join } from 'path'
|
||||
import {
|
||||
nextServer,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
import webdriver from 'next-webdriver'
|
||||
import cheerio from 'cheerio'
|
||||
import { waitFor, check } from 'next-test-utils'
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* eslint-env jest */
|
||||
/* global jasmine, webdriver, browserName */
|
||||
/* global jasmine, browserName */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { readFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { readFile } from 'fs'
|
||||
import { promisify } from 'util'
|
||||
import { join } from 'path'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
/* global webdriver */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { readFileSync } from 'fs'
|
||||
import { join, resolve as resolvePath } from 'path'
|
||||
import { renderViaHTTP, getBrowserBodyText, waitFor } from 'next-test-utils'
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* eslint-env jest */
|
||||
/* global jasmine, test, webdriver */
|
||||
/* global jasmine, test */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { join } from 'path'
|
||||
import { existsSync } from 'fs'
|
||||
import {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* eslint-env jest */
|
||||
/* global jasmine, webdriver */
|
||||
/* global jasmine */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { join } from 'path'
|
||||
import {
|
||||
getReactErrorOverlayContent,
|
||||
|
|
|
@ -6,7 +6,6 @@ const fetch = require('node-fetch')
|
|||
const getPort = require('get-port')
|
||||
const NodeEnvironment = require('jest-environment-node')
|
||||
const {
|
||||
HEADLESS,
|
||||
BROWSER_NAME,
|
||||
BROWSERSTACK,
|
||||
BROWSERSTACK_USERNAME,
|
||||
|
@ -15,7 +14,6 @@ const {
|
|||
|
||||
let browser
|
||||
let initialWindow
|
||||
let driverPort = 9515
|
||||
let browserOptions = {
|
||||
browserName: BROWSER_NAME || 'chrome'
|
||||
}
|
||||
|
@ -57,8 +55,6 @@ if (isBrowserStack) {
|
|||
...(isSafari ? safariOpts : {}),
|
||||
...(isFirefox ? firefoxOpts : {})
|
||||
}
|
||||
} else if (HEADLESS !== 'false') {
|
||||
browserOptions.chromeOptions = { args: ['--headless'] }
|
||||
}
|
||||
|
||||
const newTabPg = `
|
||||
|
@ -74,22 +70,20 @@ const newTabPg = `
|
|||
`
|
||||
|
||||
class CustomEnvironment extends NodeEnvironment {
|
||||
async createBrowser (fromWebdriver = false) {
|
||||
async createBrowser () {
|
||||
// always create new browser session if not BrowserStack
|
||||
if ((!browser && isBrowserStack) || fromWebdriver) {
|
||||
browser = isBrowserStack
|
||||
? wd.promiseChainRemote(
|
||||
'hub-cloud.browserstack.com', // seleniumHost
|
||||
80, // seleniumPort
|
||||
BROWSERSTACK_USERNAME,
|
||||
BROWSERSTACK_ACCESS_KEY
|
||||
)
|
||||
: wd.promiseChainRemote(`http://localhost:${driverPort}/`)
|
||||
if ((!browser && isBrowserStack)) {
|
||||
browser = wd.promiseChainRemote(
|
||||
'hub-cloud.browserstack.com', // seleniumHost
|
||||
80, // seleniumPort
|
||||
BROWSERSTACK_USERNAME,
|
||||
BROWSERSTACK_ACCESS_KEY
|
||||
)
|
||||
|
||||
// Setup the browser instance
|
||||
await browser.init(browserOptions)
|
||||
if (isBrowserStack) initialWindow = await browser.windowHandle()
|
||||
global.browser = browser
|
||||
initialWindow = await browser.windowHandle()
|
||||
global.bsBrowser = browser
|
||||
}
|
||||
|
||||
if (isBrowserStack) {
|
||||
|
@ -128,12 +122,10 @@ class CustomEnvironment extends NodeEnvironment {
|
|||
}
|
||||
}
|
||||
this.global.browserName = BROWSER_NAME
|
||||
|
||||
this.global.isBrowserStack = isBrowserStack
|
||||
// Mock current browser set up
|
||||
this.global.webdriver = async (appPort, pathname) => {
|
||||
if (!isBrowserStack) await this.createBrowser(true)
|
||||
this.global.bsWd = async (appPort, pathname) => {
|
||||
const url = `http://${deviceIP}:${appPort}${pathname}`
|
||||
|
||||
console.log(`\n> Loading browser with ${url}\n`)
|
||||
if (isBrowserStack) await this.freshWindow()
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
let globalTeardown
|
||||
const browser = global.browser
|
||||
const browser = global.bsBrowser
|
||||
|
||||
if (process.env.BROWSERSTACK) {
|
||||
globalTeardown = () => global.browserStackLocal.killAllProcesses(() => {})
|
||||
|
|
91
test/lib/next-webdriver.js
Normal file
91
test/lib/next-webdriver.js
Normal file
|
@ -0,0 +1,91 @@
|
|||
import wd from 'wd'
|
||||
import getPort from 'get-port'
|
||||
import waitPort from 'wait-port'
|
||||
|
||||
const doHeadless = process.env.HEADLESS !== 'false'
|
||||
let driverPort = 9515
|
||||
|
||||
let webdriver = async function (appPort, pathname) {
|
||||
if (typeof appPort === 'undefined') {
|
||||
throw new Error('appPort is undefined')
|
||||
}
|
||||
|
||||
const url = `http://localhost:${appPort}${pathname}`
|
||||
console.log(`> Start loading browser with url: ${url}`)
|
||||
|
||||
// Sometimes browser won't initialize due to some random issues.
|
||||
// So, we need to timeout the initialization and retry again.
|
||||
for (let lc = 0; lc < 5; lc++) {
|
||||
try {
|
||||
const browser = await getBrowser(url, 5000)
|
||||
console.log(`> Complete loading browser with url: ${url}`)
|
||||
return browser
|
||||
} catch (ex) {
|
||||
console.warn(`> Error when loading browser with url: ${url}`)
|
||||
|
||||
// Try restarting chromedriver max twice
|
||||
if (lc < 2) {
|
||||
const chromedriver = require('chromedriver')
|
||||
console.log('Trying to restart chromedriver with random port')
|
||||
driverPort = await getPort()
|
||||
chromedriver.stop()
|
||||
chromedriver.start([`--port=${driverPort}`])
|
||||
// https://github.com/giggio/node-chromedriver/issues/117
|
||||
await waitPort({
|
||||
port: driverPort,
|
||||
timeout: 1000 * 30 // 30 seconds
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
if (ex.message === 'TIMEOUT') continue
|
||||
throw ex
|
||||
}
|
||||
}
|
||||
|
||||
console.error(`> Tried 5 times. Cannot load the browser for url: ${url}`)
|
||||
throw new Error(`Couldn't start the browser for url: ${url}`)
|
||||
}
|
||||
|
||||
function getBrowser (url, timeout) {
|
||||
const browser = wd.promiseChainRemote(`http://localhost:${driverPort}/`)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let timeouted = false
|
||||
const timeoutHandler = setTimeout(() => {
|
||||
timeouted = true
|
||||
const error = new Error('TIMEOUT')
|
||||
reject(error)
|
||||
}, timeout)
|
||||
|
||||
browser.init({
|
||||
browserName: 'chrome',
|
||||
...(doHeadless ? {
|
||||
chromeOptions: { args: ['--headless'] }
|
||||
} : {})
|
||||
}).get(url, err => {
|
||||
if (timeouted) {
|
||||
try {
|
||||
browser.close(() => {
|
||||
// Ignore errors
|
||||
})
|
||||
} catch (err) {
|
||||
// Ignore
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
clearTimeout(timeoutHandler)
|
||||
|
||||
if (err) {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
|
||||
resolve(browser)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (global.isBrowserStack) webdriver = global.bsBrowser
|
||||
export default webdriver
|
Loading…
Reference in a new issue