diff --git a/.changeset/yellow-snails-cry.md b/.changeset/yellow-snails-cry.md
new file mode 100644
index 00000000..f827258c
--- /dev/null
+++ b/.changeset/yellow-snails-cry.md
@@ -0,0 +1,5 @@
+---
+"@webx-kit/test-utils": patch
+---
+
+feat(test-utils): add webx-launch command
diff --git a/packages/test-utils/bin/tsconfig.json b/packages/test-utils/bin/tsconfig.json
new file mode 100644
index 00000000..efaa8b3b
--- /dev/null
+++ b/packages/test-utils/bin/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": ["../tsconfig.json"],
+ "compilerOptions": {
+ "target": "ES2020",
+ "module": "ES2020",
+ "noEmit": true
+ }
+}
diff --git a/packages/test-utils/bin/webx-launch.mjs b/packages/test-utils/bin/webx-launch.mjs
new file mode 100755
index 00000000..adc0f4b3
--- /dev/null
+++ b/packages/test-utils/bin/webx-launch.mjs
@@ -0,0 +1,47 @@
+#!/usr/bin/env node
+
+// @ts-check
+///
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { chalk, fs, findMonorepoRoot } from '@modern-js/utils';
+import commander from '@modern-js/utils/commander';
+import { chromium } from '@playwright/test';
+
+commander.program.option('--path ', 'extension path', 'dist');
+
+const opts = commander.program.parse(process.argv).opts();
+
+const extensionPath = path.resolve(opts.path);
+if (!fs.existsSync(extensionPath)) throw new Error(`\`${extensionPath}\` does not exist`);
+if (!fs.statSync(extensionPath).isDirectory()) throw new Error(`\`${extensionPath}\` is not a directory`);
+
+const dirname = path.dirname(fileURLToPath(import.meta.url));
+const monorepoRoot = findMonorepoRoot(dirname);
+const userDataDir = path.resolve(
+ monorepoRoot || path.resolve(dirname, '..'),
+ 'node_modules/.cache/webx-browser-user-dir'
+);
+
+// it must be "persisted", otherwise the browser will enable incognito mode
+chromium
+ .launchPersistentContext(userDataDir, {
+ headless: false,
+ colorScheme: 'no-preference',
+ viewport: null,
+ ignoreDefaultArgs: ['--disable-extensions', '--enable-automation'],
+ args: ['--hide-crash-restore-bubble', `--load-extension=${extensionPath}`],
+ })
+ .then(async (context) => {
+ console.log(chalk.green`Start successfully`);
+
+ const outdatedPages = context.pages();
+ const page = await context.newPage();
+ await Promise.all(outdatedPages.map((page) => page.close()));
+ await page.goto(`chrome://extensions/`);
+
+ await page.evaluate(() => chrome.developerPrivate.updateProfileConfiguration({ inDeveloperMode: true }));
+ })
+ .catch((err) => {
+ console.log(chalk.red`Start failed`, err);
+ });
diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json
index 1cfce464..f2100495 100644
--- a/packages/test-utils/package.json
+++ b/packages/test-utils/package.json
@@ -1,6 +1,9 @@
{
"name": "@webx-kit/test-utils",
"version": "0.0.0",
+ "bin": {
+ "webx-launch": "bin/webx-launch.mjs"
+ },
"exports": {
"./*": {
"types": "./src/*.ts",
@@ -39,6 +42,7 @@
"lint:type": "tsc --noEmit"
},
"dependencies": {
+ "@modern-js/utils": "^2.46.1",
"@webx-kit/chrome-types": "workspace:^"
},
"devDependencies": {
diff --git a/packages/test-utils/tsconfig.build.json b/packages/test-utils/tsconfig.build.json
index 8c609f79..9962ea9c 100644
--- a/packages/test-utils/tsconfig.build.json
+++ b/packages/test-utils/tsconfig.build.json
@@ -3,5 +3,7 @@
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
- }
+ "noEmit": false
+ },
+ "include": ["./src"]
}
diff --git a/packages/test-utils/tsconfig.json b/packages/test-utils/tsconfig.json
index a1ee9de7..34dfa1a5 100644
--- a/packages/test-utils/tsconfig.json
+++ b/packages/test-utils/tsconfig.json
@@ -13,7 +13,8 @@
"experimentalDecorators": true,
"resolveJsonModule": true,
"moduleResolution": "node",
- "baseUrl": "./"
+ "baseUrl": "./",
+ "noEmit": true
},
"exclude": ["dist"]
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2fafb33c..3643764e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -397,6 +397,9 @@ importers:
packages/test-utils:
dependencies:
+ '@modern-js/utils':
+ specifier: ^2.46.1
+ version: 2.46.1
'@webx-kit/chrome-types':
specifier: workspace:^
version: link:../chrome-types
@@ -3588,7 +3591,6 @@ packages:
caniuse-lite: 1.0.30001579
lodash: 4.17.21
rslog: 1.2.0
- dev: true
/@module-federation/runtime-tools@0.0.8:
resolution: {integrity: sha512-tqx3wlVHnpWLk+vn22c0x9Nv1BqdZnoS6vdMb53IsVpbQIFP70nhhvymHUyFuPkoLzMFidS7GpG58DYT/4lvCw==}
@@ -10036,7 +10038,6 @@ packages:
/rslog@1.2.0:
resolution: {integrity: sha512-2ZFW7Jtkzt4VkwCFRTE+0lKbzSLSH7U5OM9qZ5YuKk4xVrlIJJZx9Qh/fCyfsk8H+qXbermMc7+18qKJxLQ/bw==}
engines: {node: '>=14.17.6'}
- dev: true
/rspack-manifest-plugin@5.0.0-alpha0(webpack@5.89.0):
resolution: {integrity: sha512-a84H6P/lK0x3kb0I8Qdiwxrnjt1oNW0j+7kwPMWcODJu8eYFBrTXa1t+14n18Jvg9RKIR6llCH16mYxf2d0s8A==}