Skip to content

Commit

Permalink
refactor: split client and server types
Browse files Browse the repository at this point in the history
  • Loading branch information
PaperStrike committed Oct 25, 2023
1 parent 6bea50b commit c007f53
Show file tree
Hide file tree
Showing 49 changed files with 268 additions and 129 deletions.
8 changes: 7 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@
"ignorePatterns": ["build/"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": ["./tsconfig.json", "./test/tsconfig.json"]
"project": [
"./src/cli/tsconfig.json",
"./src/client/tsconfig.json",
"./src/common/tsconfig.json",
"./src/server/tsconfig.json",
"./test/tsconfig.json"
]
},
"plugins": [
"@typescript-eslint"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ node_modules/
coverage/
build/
dist/
*.tsbuildinfo
32 changes: 17 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,29 @@
"description": "playwright, but unit test",
"version": "0.1.0",
"type": "module",
"main": "./build/index.js",
"types": "./build/index.d.ts",
"main": "./build/client/api.js",
"types": "./build/client/api.d.ts",
"exports": {
".": "./build/index.js",
"./cli": "./build/cli.js",
"./node": "./build/node.js",
".": "./build/client/api.js",
"./cli": "./build/cli/api.js",
"./node": "./build/server/api.js",
"./package.json": "./package.json"
},
"typesVersions": {
"<4.7": {
".": [
"./build/index.d.ts"
"./build/client/api.d.ts"
],
"cli": [
"./build/cli.d.ts"
"./build/cli/api.d.ts"
],
"node": [
"./build/node.d.ts"
"./build/server/api.d.ts"
]
}
},
"bin": {
"wrightplay": "./build/cli.js"
"wrightplay": "./build/cli/index.js"
},
"browser": {
"mocha": "mocha/mocha.js",
Expand All @@ -37,13 +37,14 @@
"repository": "github:PaperStrike/wrightplay",
"license": "ISC",
"scripts": {
"build": "tsc",
"build": "tsc -b",
"lint": "eslint .",
"prepare": "npm run build",
"test-entry": "ts-node-esm src/cli.ts ww=test/entry/worker.ts test/entry/*.test.*",
"test-handle": "ts-node-esm src/cli.ts test/handle/*.test.*",
"test-route": "ts-node-esm src/cli.ts test/route/*.test.*",
"test": "ts-node-esm src/cli.ts ww=test/entry/worker.ts test/**/*.test.ts !**/third-party",
"cli": "ts-node-esm src/cli/index.ts",
"test-entry": "npm run cli -- ww=test/entry/worker.ts test/entry/*.test.*",
"test-handle": "npm run cli -- test/handle/*.test.*",
"test-route": "npm run cli -- test/route/*.test.*",
"test": "npm run cli -- ww=test/entry/worker.ts test/**/*.test.ts !**/third-party",
"test-chromium": "npm test -- --browser chromium",
"test-firefox": "npm test -- --browser firefox",
"test-webkit": "npm test -- --browser webkit",
Expand All @@ -52,7 +53,8 @@
"files": [
"build",
"static",
"src"
"src",
"!*.tsbuildinfo"
],
"keywords": [
"test",
Expand Down
21 changes: 9 additions & 12 deletions src/cli.ts → src/cli/api.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
#!/usr/bin/env node

import { createRequire } from 'node:module';
import { Command, Option } from '@commander-js/extra-typings';
import Runner, { BrowserServerOptions, RunnerOptions } from './Runner.js';
import { ConfigOptions } from './node.js';
import Runner, { BrowserServerOptions, RunnerOptions } from '../server/Runner.js';
import { ConfigOptions } from '../server/api.js';
import configSearcher from './configSearcher.js';

const require = createRequire(import.meta.url);
const pkgJSON = require('../package.json') as {
const pkgJSON = require('../../package.json') as {
name: string;
version: string;
};

// Simple JSON.parse. Error by Playwright if any.
const parseBrowserServerOptions = (str: string) => JSON.parse(str) as BrowserServerOptions;
export const parseBrowserServerOptions = (str: string) => JSON.parse(str) as BrowserServerOptions;

export const program = new Command()
const command = new Command()
.version(pkgJSON.version)
.name(pkgJSON.name)
.argument('[test-or-entry...]', 'Test files and entry points. Use glob for tests, name=path for entries')
Expand All @@ -30,7 +28,7 @@ export const program = new Command()
.addOption(new Option('-d, --debug', 'Run browser in headed mode. Defaults to `false`'))
.addOption(new Option('--no-cov', 'Disable coverage file output. This only matters when `NODE_V8_COVERAGE` is set. Defaults to `false` on chromium, `true` on firefox and webkit'));

export type CLIOptions = ReturnType<typeof program.opts>;
export type CLIOptions = ReturnType<typeof command.opts>;

export const parseRunnerOptionsFromCLI = async (
testAndEntries: string[],
Expand Down Expand Up @@ -74,14 +72,13 @@ export const parseRunnerOptionsFromCLI = async (
});
};

program
.action(async (testAndEntries: string[], options: CLIOptions) => {
export const program = command
.action(async (testAndEntries, options) => {
const runnerOptionsList = await parseRunnerOptionsFromCLI(testAndEntries, options);
await runnerOptionsList.reduce(async (last, runnerOptions) => {
await last;
using runner = new Runner(runnerOptions);
const exitCode = await runner.runTests();
process.exitCode ||= exitCode;
}, Promise.resolve());
})
.parse();
});
File renamed without changes.
5 changes: 5 additions & 0 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env node

import { program } from './api.js';

program.parse();
12 changes: 12 additions & 0 deletions src/cli/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "../../build/cli",
"types": ["node"]
},
"include": ["./"],
"references": [
{ "path": "../server" }
]
}
10 changes: 5 additions & 5 deletions src/index.ts → src/client/api.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import WSClient from './WS/WSClient.js';
import WSClient from './ws/WSClient.js';
import TestInitEvent from './event/TestInitEvent.js';
import TestDoneEvent from './event/TestDoneEvent.js';

import type Route from './WS/route/Route.js';
import type RouteRequest from './WS/route/RouteRequest.js';
import type RouteHandler from './WS/route/RouteHandler.js';
import type Route from './ws/route/Route.js';
import type RouteRequest from './ws/route/RouteRequest.js';
import type RouteHandler from './ws/route/RouteHandler.js';
import type {
RouteMatcher,
RouteHandlerCallback,
RouteOptions,
} from './WS/route/RouteHandler.js';
} from './ws/route/RouteHandler.js';

export {
Route,
Expand Down
File renamed without changes.
File renamed without changes.
55 changes: 55 additions & 0 deletions src/client/runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Functions to be injected into the test page to control the client test runs.
*
* Keep these funcs self-contained so that they can be serialized and injected.
*/

// No coverage support for this kind of functions yet
/* c8 ignore start */

/**
* Dispatches an init event after the test scripts are successfully imported.
*/
export const init = (uuid: string) => {
window.dispatchEvent(new CustomEvent(`__wrightplay_${uuid}_init__`));
};

/**
* Injects the test script and resolves with the exit code.
*/
export const inject = (uuid: string) => (
new Promise<number>((resolve) => {
const script = document.createElement('script');

// Detect inject error
script.addEventListener('error', () => {
// eslint-disable-next-line no-console
console.error('Failed to inject test script');
resolve(1);
}, { once: true });

// Detect init error
const onUncaughtError = () => {
// eslint-disable-next-line no-console
console.error('Uncaught error detected while initializing the tests');
resolve(1);
};
window.addEventListener('error', onUncaughtError, { once: true });

// Detect init end
window.addEventListener(`__wrightplay_${uuid}_init__`, () => {
window.removeEventListener('error', onUncaughtError);
}, { once: true });

// Detect test done
window.addEventListener(`__wrightplay_${uuid}_done__`, ({ exitCode }) => {
window.removeEventListener('error', onUncaughtError);
resolve(exitCode);
}, { once: true });

// Inject
script.src = '/stdin.js';
script.type = 'module';
document.head.append(script);
})
);
12 changes: 12 additions & 0 deletions src/client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"lib": ["ESNext", "DOM"],
"outDir": "../../build/client"
},
"include": ["./"],
"references": [
{ "path": "../common" }
]
}
4 changes: 2 additions & 2 deletions src/WS/WSClient.ts → src/client/ws/WSClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
createRouteMeta,
parseServerMeta,
RouteServerMeta,
} from './message.js';
} from '../../common/ws/message.js';
import RouteHandler, { RouteHandlerCallback, RouteMatcher, RouteOptions } from './route/RouteHandler.js';
import RouteRequest from './route/RouteRequest.js';
import Route from './route/Route.js';
Expand Down Expand Up @@ -80,7 +80,7 @@ export default class WSClient {
return this.statusPromise;
}

bypassFetch(...fetchArgs: Parameters<WindowOrWorkerGlobalScope['fetch']>) {
bypassFetch(...fetchArgs: Parameters<typeof fetch>) {
const request = new Request(...fetchArgs);
request.headers.set(`bypass-${this.uuid}`, 'true');
return fetch(request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {
parseServerMeta,
HandleMetaBase,
HandleClientMeta,
} from '../message.js';
import * as Serializer from '../../serializer/index.js';
} from '../../../common/ws/message.js';
import * as Serializer from '../../../common/serializer/index.js';

export type Unboxed<Arg> =
Arg extends URL
Expand Down
2 changes: 1 addition & 1 deletion src/WS/route/Route.ts → src/client/ws/route/Route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createRouteMeta, parseServerMeta } from '../message.js';
import { createRouteMeta, parseServerMeta } from '../../../common/ws/message.js';
import type RouteRequest from './RouteRequest.js';

export type RouteChain = (done: boolean) => Promise<void>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import globToRegex from '../../util/globToRegex.js';
import globToRegex from '../../../common/utils/globToRegex.js';
import type Route from './Route.js';
import type RouteRequest from './RouteRequest.js';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type playwright from 'playwright-core';
import HostHandle from '../handle/HostHandle.js';
import { RouteRequestMeta } from '../message.js';
import { RouteRequestMeta } from '../../../common/ws/message.js';
import { FallbackOverrides } from './Route.js';

export default class RouteRequest {
Expand Down
37 changes: 37 additions & 0 deletions src/common/globals.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* APIs that are common to Node.js and the DOM.
*
* Better if a lib provides these types.
*
* https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1402
*/

declare global {
interface URL {
hash: string;
host: string;
hostname: string;
href: string;
readonly origin: string;
password: string;
pathname: string;
port: string;
protocol: string;
search: string;
readonly searchParams: URLSearchParams;
username: string;
toString(): string;
toJSON(): string;
}

interface URLConstructor {
new(input: string, base?: string | URL): URL;
createObjectURL(object: Blob): string;
revokeObjectURL(url: string): void;
readonly prototype: URL;
}

const URL: typeof URLConstructor;
}

export {};
3 changes: 0 additions & 3 deletions src/serializer/Handle.ts → src/common/serializer/Handle.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
export default class Handle {
constructor(
/**
* @internal
*/
readonly id: number,
) {}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
11 changes: 11 additions & 0 deletions src/common/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"lib": ["ES2022", "ESNext.Disposable"],
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "../../build/common"
},
"include": ["./"]
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit c007f53

Please sign in to comment.