@lvce-editor/test-with-playwright-worker 5.0.1 → 6.0.0

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.
Files changed (32) hide show
  1. package/LICENSE +21 -0
  2. package/dist/workerMain.js +1366 -0
  3. package/package.json +9 -14
  4. package/src/parts/Assert/Assert.js +0 -1
  5. package/src/parts/CliCommandType/CliCommandType.js +0 -2
  6. package/src/parts/Command/Command.js +0 -1
  7. package/src/parts/CommandMap/CommandMap.js +0 -6
  8. package/src/parts/ErrorCodes/ErrorCodes.js +0 -2
  9. package/src/parts/GetPort/GetPort.js +0 -5
  10. package/src/parts/GetPossibleServerPaths/GetPossibleServerPaths.js +0 -11
  11. package/src/parts/GetServerPath/GetServerPath.js +0 -14
  12. package/src/parts/GetTestState/GetTestState.js +0 -24
  13. package/src/parts/GetTests/GetTests.js +0 -26
  14. package/src/parts/IsEnoentError/IsEnoentError.js +0 -8
  15. package/src/parts/IsTestFile/IsTestFile.js +0 -8
  16. package/src/parts/Main/Main.js +0 -34
  17. package/src/parts/NoTestFilesFoundError/NoTestFilesFoundError.js +0 -8
  18. package/src/parts/Process/Process.js +0 -8
  19. package/src/parts/ProcessListeners/ProcessListeners.js +0 -3
  20. package/src/parts/RpcId/RpcId.js +0 -1
  21. package/src/parts/RunAllTests/RunAllTests.js +0 -46
  22. package/src/parts/RunTest/RunTest.js +0 -36
  23. package/src/parts/RunTests/RunTests.js +0 -44
  24. package/src/parts/SetupTests/SetupTests.js +0 -25
  25. package/src/parts/Signal/Signal.js +0 -1
  26. package/src/parts/StartBrowser/StartBrowser.js +0 -21
  27. package/src/parts/StartServer/StartServer.js +0 -29
  28. package/src/parts/TearDownTests/TearDownTests.js +0 -6
  29. package/src/parts/TestOverlayState/TestOverlayState.js +0 -3
  30. package/src/parts/TestState/TestState.js +0 -3
  31. package/src/parts/TestWorkerCommandType/TestWorkerCommandType.js +0 -1
  32. 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": "5.0.1",
4
- "description": "",
5
- "main": "src/workerMain.js",
6
- "type": "module",
3
+ "version": "6.0.0",
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
- "@lvce-editor/assert": "^1.4.0",
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
- "@types/jest": "^30.0.0"
17
+ "devDependencies": {},
18
+ "engines": {
19
+ "node": ">=22"
25
20
  }
26
21
  }
@@ -1 +0,0 @@
1
- export * from '@lvce-editor/assert'
@@ -1,2 +0,0 @@
1
- export const HandleResult = 'HandleResult'
2
- export const HandleFinalResult = 'HandleFinalResult'
@@ -1 +0,0 @@
1
- export * from '@lvce-editor/command'
@@ -1,6 +0,0 @@
1
- import * as RunAllTests from '../RunAllTests/RunAllTests.js'
2
- import * as TestWorkerCommandType from '../TestWorkerCommandType/TestWorkerCommandType.js'
3
-
4
- export const commandMap = {
5
- [TestWorkerCommandType.RunAllTests]: RunAllTests.runAllTests,
6
- }
@@ -1,2 +0,0 @@
1
- export const ENOENT = 'ENOENT'
2
- export const E_NO_TEST_FILES = 'E_NO_TEST_FILES'
@@ -1,5 +0,0 @@
1
- import _getPort from 'get-port'
2
-
3
- export const getPort = () => {
4
- return _getPort()
5
- }
@@ -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
- }
@@ -1,8 +0,0 @@
1
- import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
2
-
3
- /**
4
- * @param {any} error
5
- */
6
- export const isEnoentError = (error) => {
7
- return error && error.code === ErrorCodes.ENOENT
8
- }
@@ -1,8 +0,0 @@
1
- import { Dirent } from 'node:fs'
2
-
3
- /**
4
- * @param {Dirent} dirent
5
- */
6
- export const isTestFile = (dirent) => {
7
- return dirent.isFile() && !dirent.name.startsWith('_')
8
- }
@@ -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
- }
@@ -1,8 +0,0 @@
1
- import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
2
-
3
- export class NoTestFilesFoundError extends Error {
4
- constructor(root) {
5
- super(`No test files found at ${root}`)
6
- this.code = ErrorCodes.E_NO_TEST_FILES
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- /**
2
- *
3
- * @param {string} event
4
- * @param {any} listener
5
- */
6
- export const on = (event, listener) => {
7
- process.on(event, listener)
8
- }
@@ -1,3 +0,0 @@
1
- export const handleUncaughtExceptionMonitor = (error) => {
2
- console.log(`[test-worker] uncaught exception ${error}`)
3
- }
@@ -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,6 +0,0 @@
1
- import * as Signal from '../Signal/Signal.js'
2
-
3
- export const tearDownTests = ({ controller, child }) => {
4
- controller.abort()
5
- child.kill(Signal.SIGINT)
6
- }
@@ -1,3 +0,0 @@
1
- export const Pass = 'pass'
2
- export const Skip = 'skip'
3
- export const Fail = 'fail'
@@ -1,3 +0,0 @@
1
- export const Pass = 1
2
- export const Skip = 2
3
- export const Fail = 3
@@ -1 +0,0 @@
1
- export const RunAllTests = 'RunAllTests'
package/src/workerMain.js DELETED
@@ -1,3 +0,0 @@
1
- import * as Main from './parts/Main/Main.js'
2
-
3
- Main.main()