/
webdriver.ts
88 lines (69 loc) · 2.55 KB
/
webdriver.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import type { Browser } from 'webdriverio'
import type { Awaitable } from '@vitest/utils'
import type { BrowserProvider, BrowserProviderOptions } from '../../types/browser'
import { ensurePackageInstalled } from '../pkg'
import type { WorkspaceProject } from '../workspace'
export const webdriverBrowsers = ['firefox', 'chrome', 'edge', 'safari'] as const
export type WebdriverBrowser = typeof webdriverBrowsers[number]
export interface WebdriverProviderOptions extends BrowserProviderOptions {
browser: WebdriverBrowser
}
export class WebdriverBrowserProvider implements BrowserProvider {
public name = 'webdriverio'
private cachedBrowser: Browser | null = null
private stopSafari: () => void = () => {}
private browser!: WebdriverBrowser
private ctx!: WorkspaceProject
getSupportedBrowsers() {
return webdriverBrowsers
}
async initialize(ctx: WorkspaceProject, { browser }: WebdriverProviderOptions) {
this.ctx = ctx
this.browser = browser
const root = this.ctx.config.root
if (!await ensurePackageInstalled('webdriverio', root))
throw new Error('Cannot find "webdriverio" package. Please install it manually.')
if (browser === 'safari' && !await ensurePackageInstalled('safaridriver', root))
throw new Error('Cannot find "safaridriver" package. Please install it manually.')
}
async openBrowser() {
if (this.cachedBrowser)
return this.cachedBrowser
const options = this.ctx.config.browser
if (this.browser === 'safari') {
const safaridriver = await import('safaridriver')
safaridriver.start({ diagnose: true })
this.stopSafari = () => safaridriver.stop()
process.on('beforeExit', () => {
safaridriver.stop()
})
}
const { remote } = await import('webdriverio')
// TODO: close everything, if browser is closed from the outside
this.cachedBrowser = await remote({
logLevel: 'error',
capabilities: {
'browserName': this.browser,
'wdio:devtoolsOptions': { headless: options.headless },
},
})
return this.cachedBrowser
}
async openPage(url: string) {
const browserInstance = await this.openBrowser()
await browserInstance.url(url)
}
// TODO
catchError(_cb: (error: Error) => Awaitable<void>) {
return () => {}
}
async close() {
await Promise.all([
this.stopSafari(),
this.cachedBrowser?.sessionId ? this.cachedBrowser?.deleteSession?.() : null,
])
// TODO: right now process can only exit with timeout, if we use browser
// needs investigating
process.exit()
}
}