@lvce-editor/test-with-playwright-worker 5.0.1 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/workerMain.js +1366 -0
- package/package.json +9 -14
- package/src/parts/Assert/Assert.js +0 -1
- package/src/parts/CliCommandType/CliCommandType.js +0 -2
- package/src/parts/Command/Command.js +0 -1
- package/src/parts/CommandMap/CommandMap.js +0 -6
- package/src/parts/ErrorCodes/ErrorCodes.js +0 -2
- package/src/parts/GetPort/GetPort.js +0 -5
- package/src/parts/GetPossibleServerPaths/GetPossibleServerPaths.js +0 -11
- package/src/parts/GetServerPath/GetServerPath.js +0 -14
- package/src/parts/GetTestState/GetTestState.js +0 -24
- package/src/parts/GetTests/GetTests.js +0 -26
- package/src/parts/IsEnoentError/IsEnoentError.js +0 -8
- package/src/parts/IsTestFile/IsTestFile.js +0 -8
- package/src/parts/Main/Main.js +0 -34
- package/src/parts/NoTestFilesFoundError/NoTestFilesFoundError.js +0 -8
- package/src/parts/Process/Process.js +0 -8
- package/src/parts/ProcessListeners/ProcessListeners.js +0 -3
- package/src/parts/RpcId/RpcId.js +0 -1
- package/src/parts/RunAllTests/RunAllTests.js +0 -46
- package/src/parts/RunTest/RunTest.js +0 -36
- package/src/parts/RunTests/RunTests.js +0 -44
- package/src/parts/SetupTests/SetupTests.js +0 -25
- package/src/parts/Signal/Signal.js +0 -1
- package/src/parts/StartBrowser/StartBrowser.js +0 -21
- package/src/parts/StartServer/StartServer.js +0 -29
- package/src/parts/TearDownTests/TearDownTests.js +0 -6
- package/src/parts/TestOverlayState/TestOverlayState.js +0 -3
- package/src/parts/TestState/TestState.js +0 -3
- package/src/parts/TestWorkerCommandType/TestWorkerCommandType.js +0 -1
- package/src/workerMain.js +0 -3
package/package.json
CHANGED
|
@@ -1,26 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/test-with-playwright-worker",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "",
|
|
5
|
-
"main": "src/workerMain.js",
|
|
6
|
-
"type": "module",
|
|
3
|
+
"version": "6.0.1",
|
|
4
|
+
"description": "Worker package for test-with-playwright",
|
|
7
5
|
"repository": {
|
|
8
6
|
"type": "git",
|
|
9
7
|
"url": "git@github.com:lvce-editor/test-with-playwright.git",
|
|
10
8
|
"directory": "packages/test-with-playwright-worker"
|
|
11
9
|
},
|
|
12
|
-
"keywords": [],
|
|
13
|
-
"author": "Lvce Editor",
|
|
14
10
|
"license": "MIT",
|
|
11
|
+
"author": "Lvce Editor",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"main": "dist/workerMain.js",
|
|
15
14
|
"dependencies": {
|
|
16
|
-
"@
|
|
17
|
-
"@lvce-editor/rpc": "^4.18.0",
|
|
18
|
-
"@lvce-editor/rpc-registry": "^3.6.0",
|
|
19
|
-
"@lvce-editor/verror": "^1.7.0",
|
|
20
|
-
"@playwright/test": "1.55.0",
|
|
21
|
-
"get-port": "^7.1.0"
|
|
15
|
+
"@playwright/test": "1.55.0"
|
|
22
16
|
},
|
|
23
|
-
"devDependencies": {
|
|
24
|
-
|
|
17
|
+
"devDependencies": {},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=22"
|
|
25
20
|
}
|
|
26
21
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '@lvce-editor/assert'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '@lvce-editor/command'
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { join } from 'node:path'
|
|
2
|
-
import { pathToFileURL } from 'node:url'
|
|
3
|
-
|
|
4
|
-
export const getPossibleServerPaths = () => {
|
|
5
|
-
const toTry = [
|
|
6
|
-
'@lvce-editor/server',
|
|
7
|
-
pathToFileURL(join(process.cwd(), '..', 'server', 'node_modules', '@lvce-editor', 'server', 'index.js')).toString(),
|
|
8
|
-
pathToFileURL(join(process.cwd(), '..', 'build', 'node_modules', '@lvce-editor', 'server', 'index.js')).toString(),
|
|
9
|
-
]
|
|
10
|
-
return toTry
|
|
11
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import * as GetPossibleServerPaths from '../GetPossibleServerPaths/GetPossibleServerPaths.js'
|
|
2
|
-
|
|
3
|
-
export const getServerPath = async () => {
|
|
4
|
-
const toTry = GetPossibleServerPaths.getPossibleServerPaths()
|
|
5
|
-
for (const path of toTry) {
|
|
6
|
-
try {
|
|
7
|
-
const { serverPath } = await import(path)
|
|
8
|
-
return serverPath
|
|
9
|
-
} catch (error) {
|
|
10
|
-
// ignore
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
throw new Error(`[test-with-playwright] server path not found`)
|
|
14
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import * as TestOverlayState from '../TestOverlayState/TestOverlayState.js'
|
|
2
|
-
import * as TestState from '../TestState/TestState.js'
|
|
3
|
-
|
|
4
|
-
export const getTestState = (testOverlayState, text) => {
|
|
5
|
-
switch (testOverlayState) {
|
|
6
|
-
case TestOverlayState.Pass:
|
|
7
|
-
return {
|
|
8
|
-
status: TestState.Pass,
|
|
9
|
-
error: '',
|
|
10
|
-
}
|
|
11
|
-
case TestOverlayState.Skip:
|
|
12
|
-
return {
|
|
13
|
-
status: TestState.Skip,
|
|
14
|
-
error: '',
|
|
15
|
-
}
|
|
16
|
-
case TestOverlayState.Fail:
|
|
17
|
-
return {
|
|
18
|
-
status: TestState.Fail,
|
|
19
|
-
error: `${text}`,
|
|
20
|
-
}
|
|
21
|
-
default:
|
|
22
|
-
throw new Error(`unexpected test state: ${testOverlayState}`)
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { VError } from '@lvce-editor/verror'
|
|
2
|
-
import { readdir } from 'fs/promises'
|
|
3
|
-
import * as IsEnoentError from '../IsEnoentError/IsEnoentError.js'
|
|
4
|
-
import * as IsTestFile from '../IsTestFile/IsTestFile.js'
|
|
5
|
-
import { NoTestFilesFoundError } from '../NoTestFilesFoundError/NoTestFilesFoundError.js'
|
|
6
|
-
|
|
7
|
-
const getName = (dirent) => {
|
|
8
|
-
return dirent.name
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @param {string} testSrc
|
|
13
|
-
*/
|
|
14
|
-
export const getTests = async (testSrc) => {
|
|
15
|
-
try {
|
|
16
|
-
const dirents = await readdir(testSrc, {
|
|
17
|
-
withFileTypes: true,
|
|
18
|
-
})
|
|
19
|
-
return dirents.filter(IsTestFile.isTestFile).map(getName)
|
|
20
|
-
} catch (error) {
|
|
21
|
-
if (IsEnoentError.isEnoentError(error)) {
|
|
22
|
-
throw new NoTestFilesFoundError(testSrc)
|
|
23
|
-
}
|
|
24
|
-
throw new VError(error, `Failed to get test files`)
|
|
25
|
-
}
|
|
26
|
-
}
|
package/src/parts/Main/Main.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { NodeWorkerRpcClient } from '@lvce-editor/rpc'
|
|
2
|
-
import * as CommandMap from '../CommandMap/CommandMap.js'
|
|
3
|
-
import * as Process from '../Process/Process.js'
|
|
4
|
-
import * as ProcessListeners from '../ProcessListeners/ProcessListeners.js'
|
|
5
|
-
import { set } from '@lvce-editor/rpc-registry'
|
|
6
|
-
import { Cli } from '../RpcId/RpcId.js'
|
|
7
|
-
|
|
8
|
-
const handleDisconnect = () => {
|
|
9
|
-
console.log('[test-worker] disconnected')
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const handleExit = () => {
|
|
13
|
-
console.log('[test-worker] exiting')
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const handleSigint = () => {
|
|
17
|
-
console.log('[test-worker] sigint')
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const handleSigTerm = () => {
|
|
21
|
-
console.log('[test-worker] sigterm')
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const main = async () => {
|
|
25
|
-
Process.on('disconnect', handleDisconnect)
|
|
26
|
-
Process.on('exit', handleExit)
|
|
27
|
-
Process.on('SIGINT', handleSigint)
|
|
28
|
-
Process.on('SIGTERM', handleSigTerm)
|
|
29
|
-
Process.on('uncaughtExceptionMonitor', ProcessListeners.handleUncaughtExceptionMonitor)
|
|
30
|
-
const rpc = await NodeWorkerRpcClient.create({
|
|
31
|
-
commandMap: CommandMap.commandMap,
|
|
32
|
-
})
|
|
33
|
-
set(Cli, rpc)
|
|
34
|
-
}
|
package/src/parts/RpcId/RpcId.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const Cli = 6001
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { get } from '@lvce-editor/rpc-registry'
|
|
2
|
-
import { join } from 'path'
|
|
3
|
-
import * as Assert from '../Assert/Assert.js'
|
|
4
|
-
import * as CliCommandType from '../CliCommandType/CliCommandType.js'
|
|
5
|
-
import * as GetTests from '../GetTests/GetTests.js'
|
|
6
|
-
import { Cli } from '../RpcId/RpcId.js'
|
|
7
|
-
import * as RunTests from '../RunTests/RunTests.js'
|
|
8
|
-
import * as SetupTests from '../SetupTests/SetupTests.js'
|
|
9
|
-
import * as TearDownTests from '../TearDownTests/TearDownTests.js'
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @param {string} extensionPath
|
|
13
|
-
* @param {string} testPath
|
|
14
|
-
* @param {string} cwd
|
|
15
|
-
* @param {boolean} headless
|
|
16
|
-
* @param {number} headless
|
|
17
|
-
*/
|
|
18
|
-
export const runAllTests = async (extensionPath, testPath, cwd, headless, timeout) => {
|
|
19
|
-
Assert.string(extensionPath)
|
|
20
|
-
Assert.string(testPath)
|
|
21
|
-
Assert.string(cwd)
|
|
22
|
-
Assert.boolean(headless)
|
|
23
|
-
Assert.number(timeout)
|
|
24
|
-
const rpc = get(Cli)
|
|
25
|
-
const controller = new AbortController()
|
|
26
|
-
const signal = controller.signal
|
|
27
|
-
const { page, child, port } = await SetupTests.setupTests({
|
|
28
|
-
signal,
|
|
29
|
-
headless,
|
|
30
|
-
onlyExtension: extensionPath,
|
|
31
|
-
testPath,
|
|
32
|
-
})
|
|
33
|
-
const testSrc = join(testPath, 'src')
|
|
34
|
-
const tests = await GetTests.getTests(testSrc)
|
|
35
|
-
const onResult = async (result) => {
|
|
36
|
-
await rpc.invoke(CliCommandType.HandleResult, result)
|
|
37
|
-
}
|
|
38
|
-
const onFinalResult = (finalResult) => {
|
|
39
|
-
rpc.invoke(CliCommandType.HandleFinalResult, finalResult)
|
|
40
|
-
}
|
|
41
|
-
await RunTests.runTests({ testSrc, tests, headless, port, page, timeout, onResult, onFinalResult })
|
|
42
|
-
await TearDownTests.tearDownTests({
|
|
43
|
-
controller,
|
|
44
|
-
child,
|
|
45
|
-
})
|
|
46
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { expect } from '@playwright/test'
|
|
2
|
-
import { basename } from 'node:path'
|
|
3
|
-
import * as GetTestState from '../GetTestState/GetTestState.js'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @param {string} absolutePath
|
|
7
|
-
* @param {number} port
|
|
8
|
-
*/
|
|
9
|
-
const getUrlFromTestFile = (absolutePath, port) => {
|
|
10
|
-
const baseName = basename(absolutePath)
|
|
11
|
-
const htmlFileName = baseName.slice(0, -'.js'.length) + '.html'
|
|
12
|
-
return `http://localhost:${port}/tests/${htmlFileName}`
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const runTest = async ({ test, page, testSrc, port, timeout }) => {
|
|
16
|
-
const start = performance.now()
|
|
17
|
-
const url = getUrlFromTestFile(test, port)
|
|
18
|
-
await page.goto(url, {
|
|
19
|
-
waitUntil: 'networkidle',
|
|
20
|
-
})
|
|
21
|
-
const testOverlay = page.locator('#TestOverlay')
|
|
22
|
-
await expect(testOverlay).toBeVisible({
|
|
23
|
-
timeout,
|
|
24
|
-
})
|
|
25
|
-
const text = await testOverlay.textContent()
|
|
26
|
-
const testOverlayState = await testOverlay.getAttribute('data-state')
|
|
27
|
-
const testState = GetTestState.getTestState(testOverlayState)
|
|
28
|
-
const end = performance.now()
|
|
29
|
-
return {
|
|
30
|
-
...testState,
|
|
31
|
-
name: test,
|
|
32
|
-
start,
|
|
33
|
-
end,
|
|
34
|
-
error: text,
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import * as RunTest from '../RunTest/RunTest.js'
|
|
2
|
-
import * as TestState from '../TestState/TestState.js'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
*
|
|
6
|
-
* @param {{testSrc:string, tests:string[], headless:boolean, page: import('@playwright/test').Page, port:number, timeout:number, onResult:any, onFinalResult:any}} param0
|
|
7
|
-
*/
|
|
8
|
-
export const runTests = async ({ testSrc, tests, headless, page, port, timeout, onResult, onFinalResult }) => {
|
|
9
|
-
let failed = 0
|
|
10
|
-
let skipped = 0
|
|
11
|
-
let passed = 0
|
|
12
|
-
const start = performance.now()
|
|
13
|
-
for (const test of tests) {
|
|
14
|
-
const result = await RunTest.runTest({
|
|
15
|
-
test,
|
|
16
|
-
page,
|
|
17
|
-
testSrc,
|
|
18
|
-
port,
|
|
19
|
-
timeout,
|
|
20
|
-
})
|
|
21
|
-
await onResult(result)
|
|
22
|
-
switch (result.status) {
|
|
23
|
-
case TestState.Fail:
|
|
24
|
-
failed++
|
|
25
|
-
break
|
|
26
|
-
case TestState.Skip:
|
|
27
|
-
skipped++
|
|
28
|
-
break
|
|
29
|
-
case TestState.Pass:
|
|
30
|
-
passed++
|
|
31
|
-
break
|
|
32
|
-
default:
|
|
33
|
-
break
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
const end = performance.now()
|
|
37
|
-
await onFinalResult({
|
|
38
|
-
passed,
|
|
39
|
-
failed,
|
|
40
|
-
skipped,
|
|
41
|
-
start,
|
|
42
|
-
end,
|
|
43
|
-
})
|
|
44
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import * as StartBrowser from '../StartBrowser/StartBrowser.js'
|
|
2
|
-
import * as StartServer from '../StartServer/StartServer.js'
|
|
3
|
-
import * as GetPort from '../GetPort/GetPort.js'
|
|
4
|
-
import * as GetServerPath from '../GetServerPath/GetServerPath.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
*
|
|
8
|
-
* @param {{signal:AbortSignal, headless: boolean, onlyExtension:string, testPath:string}} options
|
|
9
|
-
* @returns
|
|
10
|
-
*/
|
|
11
|
-
export const setupTests = async ({ signal, headless, onlyExtension, testPath }) => {
|
|
12
|
-
const port = await GetPort.getPort()
|
|
13
|
-
const { browser, page } = await StartBrowser.startBrowser({
|
|
14
|
-
signal,
|
|
15
|
-
headless,
|
|
16
|
-
})
|
|
17
|
-
const serverPath = await GetServerPath.getServerPath()
|
|
18
|
-
const child = await StartServer.startServer({ signal, port, serverPath, onlyExtension, testPath })
|
|
19
|
-
return {
|
|
20
|
-
port,
|
|
21
|
-
browser,
|
|
22
|
-
page,
|
|
23
|
-
child,
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const SIGINT = 'SIGINT'
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { chromium } from '@playwright/test'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
* @param {{signal:AbortSignal, headless:boolean}} options
|
|
6
|
-
* @returns
|
|
7
|
-
*/
|
|
8
|
-
export const startBrowser = async ({ signal, headless }) => {
|
|
9
|
-
const browser = await chromium.launch({
|
|
10
|
-
headless,
|
|
11
|
-
})
|
|
12
|
-
const page = await browser.newPage()
|
|
13
|
-
signal.addEventListener('abort', async () => {
|
|
14
|
-
await page.close()
|
|
15
|
-
await browser.close()
|
|
16
|
-
})
|
|
17
|
-
return {
|
|
18
|
-
browser,
|
|
19
|
-
page,
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { fork } from 'child_process'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
* @param {{signal:AbortSignal, port:number, serverPath:string, onlyExtension:string, testPath:string}} param0
|
|
6
|
-
* @returns
|
|
7
|
-
*/
|
|
8
|
-
export const startServer = async ({ signal, port, serverPath, onlyExtension, testPath }) => {
|
|
9
|
-
const child = fork(serverPath, {
|
|
10
|
-
stdio: 'inherit',
|
|
11
|
-
// signal,
|
|
12
|
-
env: {
|
|
13
|
-
...process.env,
|
|
14
|
-
PORT: String(port),
|
|
15
|
-
ONLY_EXTENSION: onlyExtension,
|
|
16
|
-
TEST_PATH: testPath,
|
|
17
|
-
},
|
|
18
|
-
})
|
|
19
|
-
child.on('error', (x) => {
|
|
20
|
-
if (x.name === 'AbortError') {
|
|
21
|
-
return
|
|
22
|
-
}
|
|
23
|
-
console.log('child error', x)
|
|
24
|
-
})
|
|
25
|
-
await new Promise((resolve) => {
|
|
26
|
-
child.on('message', resolve)
|
|
27
|
-
})
|
|
28
|
-
return child
|
|
29
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const RunAllTests = 'RunAllTests'
|
package/src/workerMain.js
DELETED