Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 45 additions & 24 deletions packages/e2e/tests/edgedriver.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,59 @@ import { remote } from 'webdriverio'
import fs from 'node:fs/promises'
import path from 'node:path'
import os from 'node:os'
import { beforeEach, describe, it } from 'vitest'
import { beforeEach, afterEach, describe, it } from 'vitest'

import { start, download, findEdgePath } from 'edgedriver'

/**
* Force-kill any leftover msedgedriver/Edge processes. Sessions started via
* `wdio:edgedriverOptions.binary` have their driver process managed
* internally by WebdriverIO - deleteSession() ends the WebDriver session but
* doesn't guarantee that process has actually exited yet. A lingering
* instance either blocks deleting its own binary on Windows (EPERM: file
* still in use) or, on Linux/macOS, silently keeps running and consuming
* memory into the next test (surfaces as a bare "Killed" + exit 137).
*/
function killDriverProcesses() {
const isWindows = process.platform === 'win32'
const patterns = isWindows ? ['msedgedriver.exe', 'msedge.exe'] : ['msedgedriver', 'microsoft-edge']
for (const pattern of patterns) {
try {
execSync(isWindows ? `taskkill /IM ${pattern} /F /T` : `pkill -9 -f ${pattern}`, { stdio: 'ignore' })
} catch {
// no matching process running, nothing to clean up
}
}
}

describe('Edgedriver E2E Tests', () => {
const port = 4444
/**
* Give every test its own driver cache dir instead of the shared default
* (EDGEDRIVER_CACHE_DIR or os.tmpdir()). Tests used to all download into
* the same /tmp/msedgedriver and delete-then-redownload it between tests,
* which raced against whatever process the previous test hadn't fully
* torn down yet.
*/
let cacheDir = ''

beforeEach(async () => {
const tempDir = process.env.EDGEDRIVER_CACHE_DIR || os.tmpdir()
const edgedriverCachePath = tempDir ? path.resolve(tempDir, 'msedgedriver') : ''
if (edgedriverCachePath && await fs.lstat(edgedriverCachePath).catch(() => false)) {
console.log(`Removing existing Edge binary at ${edgedriverCachePath}`)
await fs.unlink(edgedriverCachePath)
}

const edgedriverPath = process.env.EDGE_BINARY_PATH ? path.resolve(process.env.EDGE_BINARY_PATH, 'msedgedriver') : ''
if (edgedriverPath && await fs.lstat(edgedriverPath).catch(() => false)) {
console.log(`Removing existing Edge binary at ${edgedriverPath}`)
await fs.unlink(edgedriverPath)
}
cacheDir = await fs.mkdtemp(path.join(os.tmpdir(), 'edgedriver-e2e-'))
killDriverProcesses()
})

try {
// Kill pending processes
execSync(`kill -9 $(lsof -t -i :${port})`)
console.log(`Successfully killed process on port ${port}`)
} catch {
console.log(`No process found running on port ${port}, or insufficient permissions.`)
}
afterEach(async () => {
killDriverProcesses()
/**
* maxRetries/retryDelay: Windows can lag briefly between a process
* exiting and the OS actually releasing its handle on the binary,
* even after killDriverProcesses() above returns.
*/
await fs.rm(cacheDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 200 })
})

it('start edgedriver manually', async () => {
const port = 4444
const cp = await start({ port })
const cp = await start({ port, cacheDir })

try {
await waitPort({ port: 4444 })
Expand All @@ -57,11 +77,12 @@ describe('Edgedriver E2E Tests', () => {
await browser.deleteSession()
} finally {
cp.kill()
await new Promise((resolve) => cp.once('exit', resolve))
}
})

it('start specific edgedriver', async () => {
const binary = await download()
const binary = await download(undefined, cacheDir)

const browser = await remote({
automationProtocol: 'webdriver',
Expand All @@ -80,7 +101,7 @@ describe('Edgedriver E2E Tests', () => {
})

it('start with missing architecture', async () => {
const binary = await download('152.0.4191.77')
const binary = await download('152.0.4191.77', cacheDir)

const browser = await remote({
automationProtocol: 'webdriver',
Expand Down
Loading