@extenshi/cli 0.21.0 → 0.22.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 (107) hide show
  1. package/README.md +4 -0
  2. package/dist/amo-source-detect.d.ts +18 -0
  3. package/dist/amo-source-detect.d.ts.map +1 -0
  4. package/dist/amo-source-detect.js +41 -0
  5. package/dist/amo-source-detect.js.map +1 -0
  6. package/dist/amo-source.d.ts +41 -0
  7. package/dist/amo-source.d.ts.map +1 -0
  8. package/dist/amo-source.js +240 -0
  9. package/dist/amo-source.js.map +1 -0
  10. package/dist/amowebstore-md.d.ts +38 -0
  11. package/dist/amowebstore-md.d.ts.map +1 -0
  12. package/dist/amowebstore-md.js +118 -0
  13. package/dist/amowebstore-md.js.map +1 -0
  14. package/dist/auto-evidence.d.ts +100 -0
  15. package/dist/auto-evidence.d.ts.map +1 -0
  16. package/dist/auto-evidence.js +197 -0
  17. package/dist/auto-evidence.js.map +1 -0
  18. package/dist/cli.js +265 -8
  19. package/dist/cli.js.map +1 -1
  20. package/dist/edgewebstore-md.d.ts +26 -0
  21. package/dist/edgewebstore-md.d.ts.map +1 -0
  22. package/dist/edgewebstore-md.js +95 -0
  23. package/dist/edgewebstore-md.js.map +1 -0
  24. package/dist/evidence-ingest.d.ts +60 -0
  25. package/dist/evidence-ingest.d.ts.map +1 -0
  26. package/dist/evidence-ingest.js +141 -0
  27. package/dist/evidence-ingest.js.map +1 -0
  28. package/dist/firefox-rdp.d.ts +55 -0
  29. package/dist/firefox-rdp.d.ts.map +1 -0
  30. package/dist/firefox-rdp.js +203 -0
  31. package/dist/firefox-rdp.js.map +1 -0
  32. package/dist/gecko-id.d.ts +55 -0
  33. package/dist/gecko-id.d.ts.map +1 -0
  34. package/dist/gecko-id.js +132 -0
  35. package/dist/gecko-id.js.map +1 -0
  36. package/dist/generate-listing.d.ts +19 -8
  37. package/dist/generate-listing.d.ts.map +1 -1
  38. package/dist/generate-listing.js +66 -18
  39. package/dist/generate-listing.js.map +1 -1
  40. package/dist/icon.d.ts +18 -0
  41. package/dist/icon.d.ts.map +1 -1
  42. package/dist/icon.js +29 -20
  43. package/dist/icon.js.map +1 -1
  44. package/dist/media.d.ts +42 -0
  45. package/dist/media.d.ts.map +1 -0
  46. package/dist/media.js +96 -0
  47. package/dist/media.js.map +1 -0
  48. package/dist/package.d.ts +163 -0
  49. package/dist/package.d.ts.map +1 -0
  50. package/dist/package.js +500 -0
  51. package/dist/package.js.map +1 -0
  52. package/dist/page.d.ts +10 -0
  53. package/dist/page.d.ts.map +1 -1
  54. package/dist/page.js +32 -2
  55. package/dist/page.js.map +1 -1
  56. package/dist/pay-contract.d.ts +10 -3
  57. package/dist/pay-contract.d.ts.map +1 -1
  58. package/dist/pay-contract.js +9 -0
  59. package/dist/pay-contract.js.map +1 -1
  60. package/dist/pay-test-cycle.d.ts +40 -0
  61. package/dist/pay-test-cycle.d.ts.map +1 -0
  62. package/dist/pay-test-cycle.js +207 -0
  63. package/dist/pay-test-cycle.js.map +1 -0
  64. package/dist/pay.d.ts +1 -1
  65. package/dist/pay.d.ts.map +1 -1
  66. package/dist/pay.js +1 -0
  67. package/dist/pay.js.map +1 -1
  68. package/dist/project.d.ts +39 -1
  69. package/dist/project.d.ts.map +1 -1
  70. package/dist/project.js +231 -20
  71. package/dist/project.js.map +1 -1
  72. package/dist/publish.d.ts +33 -0
  73. package/dist/publish.d.ts.map +1 -1
  74. package/dist/publish.js +113 -2
  75. package/dist/publish.js.map +1 -1
  76. package/dist/review-checks.d.ts +13 -0
  77. package/dist/review-checks.d.ts.map +1 -1
  78. package/dist/review-checks.js.map +1 -1
  79. package/dist/review-risk.d.ts +10 -1
  80. package/dist/review-risk.d.ts.map +1 -1
  81. package/dist/review-risk.js +1 -0
  82. package/dist/review-risk.js.map +1 -1
  83. package/dist/scan.d.ts +3 -2
  84. package/dist/scan.d.ts.map +1 -1
  85. package/dist/scan.js +4 -2
  86. package/dist/scan.js.map +1 -1
  87. package/dist/screenshots-scenes.d.ts +1383 -0
  88. package/dist/screenshots-scenes.d.ts.map +1 -0
  89. package/dist/screenshots-scenes.js +276 -0
  90. package/dist/screenshots-scenes.js.map +1 -0
  91. package/dist/screenshots.d.ts +145 -0
  92. package/dist/screenshots.d.ts.map +1 -0
  93. package/dist/screenshots.js +557 -0
  94. package/dist/screenshots.js.map +1 -0
  95. package/dist/smoke.d.ts +81 -0
  96. package/dist/smoke.d.ts.map +1 -0
  97. package/dist/smoke.js +491 -0
  98. package/dist/smoke.js.map +1 -0
  99. package/dist/store-assets.d.ts +139 -0
  100. package/dist/store-assets.d.ts.map +1 -0
  101. package/dist/store-assets.js +582 -0
  102. package/dist/store-assets.js.map +1 -0
  103. package/dist/zip.d.ts +57 -0
  104. package/dist/zip.d.ts.map +1 -0
  105. package/dist/zip.js +134 -0
  106. package/dist/zip.js.map +1 -0
  107. package/package.json +4 -3
@@ -0,0 +1,81 @@
1
+ /**
2
+ * `extenshi test smoke <zip> --browser chromium|edge|firefox` — install the
3
+ * EXACT packaged zip in a real browser and check that it actually works:
4
+ * it loads, its service worker / background starts, the browser reports no
5
+ * manifest errors, and its popup / options / side-panel pages open without
6
+ * console errors.
7
+ *
8
+ * Engines (all optional, resolved lazily — the CLI install stays small):
9
+ * chromium Playwright's bundled Chromium (`npx playwright install chromium`).
10
+ * Branded Google Chrome ignores --load-extension since 137, so the
11
+ * leg runs on Chromium — the same engine Chrome ships.
12
+ * edge Installed Microsoft Edge through Playwright's `msedge` channel.
13
+ * firefox Any Firefox binary; no npm dependency. The zip is installed as a
14
+ * temporary add-on over the Remote Debugging Protocol (firefox-rdp).
15
+ *
16
+ * Chromium engines get the zip extracted to a temp directory (they load
17
+ * unpacked extensions only); Firefox installs the zip file itself. Either way
18
+ * the bytes are the package's, and the result carries its sha256.
19
+ *
20
+ * Limits, stated in every result: the popup is opened as a tab, not from the
21
+ * toolbar, and no page is interacted with — this proves the package boots
22
+ * clean, not that its features work.
23
+ */
24
+ export declare const SMOKE_ENGINES: readonly ["chromium", "edge", "firefox"];
25
+ export type SmokeEngine = (typeof SMOKE_ENGINES)[number];
26
+ /** The store browser the evidence is recorded for. */
27
+ export declare const ENGINE_BROWSER: Record<SmokeEngine, 'chrome' | 'edge' | 'firefox'>;
28
+ export declare function parseSmokeEngine(value: string | undefined): SmokeEngine;
29
+ export type CheckStatus = 'passed' | 'failed' | 'skipped';
30
+ export interface SmokeCheck {
31
+ name: string;
32
+ status: CheckStatus;
33
+ detail?: string;
34
+ }
35
+ export interface SmokeResult {
36
+ artifact: string;
37
+ sha256: string;
38
+ browser: SmokeEngine;
39
+ engine: {
40
+ name: string;
41
+ version?: string;
42
+ browserVersion?: string;
43
+ channel?: string;
44
+ binary?: string;
45
+ };
46
+ extensionId?: string;
47
+ status: 'passed' | 'failed';
48
+ checks: SmokeCheck[];
49
+ limits: string[];
50
+ }
51
+ type Json = Record<string, any>;
52
+ export interface ExtensionPage {
53
+ role: 'popup' | 'options' | 'side panel' | 'sidebar';
54
+ path: string;
55
+ }
56
+ /** The extension's own pages a user can open, as the manifest declares them. */
57
+ export declare function extensionPages(manifest: Json): ExtensionPage[];
58
+ /** Checks that need no browser: the files the manifest names exist, and Firefox has a real add-on ID. */
59
+ export declare function staticChecks(manifest: Json, paths: Set<string>, engine: SmokeEngine): SmokeCheck[];
60
+ export interface SmokeOptions {
61
+ artifactPath: string;
62
+ engine: SmokeEngine;
63
+ /** Per-wait budget in ms (service worker start, page settle is a fraction of it). */
64
+ timeoutMs?: number;
65
+ headed?: boolean;
66
+ /** Firefox binary; default: FIREFOX_BIN, standard locations, PATH. */
67
+ firefoxBinary?: string;
68
+ /** Chromium/Edge executable override (Playwright `executablePath`). */
69
+ browserPath?: string;
70
+ /** Where to resolve Playwright from first (default: cwd). */
71
+ cwd?: string;
72
+ }
73
+ export declare function runSmoke(options: SmokeOptions): Promise<SmokeResult>;
74
+ /** Resolve Playwright from the project first, then next to the CLI (global installs, CI tool prefixes). */
75
+ export declare function loadPlaywright(cwd?: string): Promise<{
76
+ chromium: any;
77
+ version?: string;
78
+ }>;
79
+ export declare function renderSmoke(result: SmokeResult): string;
80
+ export {};
81
+ //# sourceMappingURL=smoke.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smoke.d.ts","sourceRoot":"","sources":["../src/smoke.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAcH,eAAO,MAAM,aAAa,0CAA2C,CAAA;AACrE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AACxD,sDAAsD;AACtD,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,WAAW,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAI7E,CAAA;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CAMvE;AAED,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAA;AACzD,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,WAAW,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,WAAW,CAAA;IACpB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACtG,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAC3B,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,MAAM,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAQ/B,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAAA;IACpD,IAAI,EAAE,MAAM,CAAA;CACZ;AAED,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,IAAI,GAAG,aAAa,EAAE,CAgB9D;AA+BD,yGAAyG;AACzG,wBAAgB,YAAY,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,UAAU,EAAE,CAsBlG;AAED,MAAM,WAAW,YAAY;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,WAAW,CAAA;IACnB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAA;CACZ;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA2B1E;AASD,2GAA2G;AAC3G,wBAAsB,cAAc,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAwBtG;AA6VD,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAOvD"}
package/dist/smoke.js ADDED
@@ -0,0 +1,491 @@
1
+ /**
2
+ * `extenshi test smoke <zip> --browser chromium|edge|firefox` — install the
3
+ * EXACT packaged zip in a real browser and check that it actually works:
4
+ * it loads, its service worker / background starts, the browser reports no
5
+ * manifest errors, and its popup / options / side-panel pages open without
6
+ * console errors.
7
+ *
8
+ * Engines (all optional, resolved lazily — the CLI install stays small):
9
+ * chromium Playwright's bundled Chromium (`npx playwright install chromium`).
10
+ * Branded Google Chrome ignores --load-extension since 137, so the
11
+ * leg runs on Chromium — the same engine Chrome ships.
12
+ * edge Installed Microsoft Edge through Playwright's `msedge` channel.
13
+ * firefox Any Firefox binary; no npm dependency. The zip is installed as a
14
+ * temporary add-on over the Remote Debugging Protocol (firefox-rdp).
15
+ *
16
+ * Chromium engines get the zip extracted to a temp directory (they load
17
+ * unpacked extensions only); Firefox installs the zip file itself. Either way
18
+ * the bytes are the package's, and the result carries its sha256.
19
+ *
20
+ * Limits, stated in every result: the popup is opened as a tab, not from the
21
+ * toolbar, and no page is interacted with — this proves the package boots
22
+ * clean, not that its features work.
23
+ */
24
+ import { createHash, randomUUID } from 'node:crypto';
25
+ import fs from 'node:fs';
26
+ import { createRequire } from 'node:module';
27
+ import os from 'node:os';
28
+ import path from 'node:path';
29
+ import { fileURLToPath, pathToFileURL } from 'node:url';
30
+ import JSZip from 'jszip';
31
+ import { InvalidInputError } from './expected-error.js';
32
+ import { findFirefox, launchFirefox } from './firefox-rdp.js';
33
+ import { isPlaceholderGeckoId, isValidGeckoId } from './gecko-id.js';
34
+ import { manifestGeckoId, manifestReferences } from './package.js';
35
+ export const SMOKE_ENGINES = ['chromium', 'edge', 'firefox'];
36
+ /** The store browser the evidence is recorded for. */
37
+ export const ENGINE_BROWSER = {
38
+ chromium: 'chrome',
39
+ edge: 'edge',
40
+ firefox: 'firefox',
41
+ };
42
+ export function parseSmokeEngine(value) {
43
+ const v = (value ?? '').trim().toLowerCase();
44
+ const engine = v === 'chrome' ? 'chromium' : v === 'msedge' ? 'edge' : v;
45
+ if (!SMOKE_ENGINES.includes(engine))
46
+ throw new InvalidInputError('--browser must be one of: chromium (alias chrome), edge, firefox');
47
+ return engine;
48
+ }
49
+ const LIMITS = [
50
+ 'The popup is opened as a regular tab, not from the toolbar button.',
51
+ 'Pages are opened, not interacted with: this proves the package boots without errors, not that its features work.',
52
+ 'Content scripts are not exercised (no target site is visited).',
53
+ ];
54
+ /** The extension's own pages a user can open, as the manifest declares them. */
55
+ export function extensionPages(manifest) {
56
+ const pages = [];
57
+ const add = (role, value) => {
58
+ if (typeof value === 'string' &&
59
+ value.trim() &&
60
+ !pages.some((p) => p.path === value.trim().replace(/^\.?\/+/, '')))
61
+ pages.push({ role, path: value.trim().replace(/^\.?\/+/, '') });
62
+ };
63
+ for (const key of ['action', 'browser_action', 'page_action'])
64
+ add('popup', manifest[key]?.default_popup);
65
+ add('options', manifest.options_ui?.page);
66
+ add('options', manifest.options_page);
67
+ add('side panel', manifest.side_panel?.default_path);
68
+ add('sidebar', manifest.sidebar_action?.default_panel);
69
+ return pages;
70
+ }
71
+ async function readPackage(bytes) {
72
+ let zip;
73
+ try {
74
+ zip = await JSZip.loadAsync(bytes);
75
+ }
76
+ catch (error) {
77
+ throw new InvalidInputError(`Not a readable zip: ${error.message}`);
78
+ }
79
+ const entry = zip.file('manifest.json');
80
+ if (!entry)
81
+ throw new InvalidInputError('The package has no manifest.json at its root.');
82
+ let manifest;
83
+ try {
84
+ manifest = JSON.parse((await entry.async('string')).replace(/^/, ''));
85
+ }
86
+ catch (error) {
87
+ throw new InvalidInputError(`manifest.json is not valid JSON: ${error.message}`);
88
+ }
89
+ const paths = new Set(Object.values(zip.files)
90
+ .filter((f) => !f.dir)
91
+ .map((f) => f.name));
92
+ return { manifest, paths, zip };
93
+ }
94
+ /** Checks that need no browser: the files the manifest names exist, and Firefox has a real add-on ID. */
95
+ export function staticChecks(manifest, paths, engine) {
96
+ const missing = manifestReferences(manifest).filter((ref) => !paths.has(ref));
97
+ const checks = [
98
+ missing.length
99
+ ? { name: 'manifest references exist', status: 'failed', detail: `missing: ${missing.join(', ')}` }
100
+ : { name: 'manifest references exist', status: 'passed' },
101
+ ];
102
+ if (engine === 'firefox') {
103
+ const id = manifestGeckoId(manifest);
104
+ checks.push(!id
105
+ ? {
106
+ name: 'Firefox add-on ID',
107
+ status: 'failed',
108
+ detail: 'browser_specific_settings.gecko.id is missing',
109
+ }
110
+ : isPlaceholderGeckoId(id) || !isValidGeckoId(id)
111
+ ? { name: 'Firefox add-on ID', status: 'failed', detail: `"${id}" is a placeholder or invalid` }
112
+ : { name: 'Firefox add-on ID', status: 'passed', detail: id });
113
+ }
114
+ return checks;
115
+ }
116
+ export async function runSmoke(options) {
117
+ const artifact = path.resolve(options.artifactPath);
118
+ const stat = fs.statSync(artifact, { throwIfNoEntry: false });
119
+ if (!stat?.isFile())
120
+ throw new InvalidInputError(`Package not found: ${options.artifactPath}`);
121
+ const bytes = fs.readFileSync(artifact);
122
+ const sha256 = createHash('sha256').update(bytes).digest('hex');
123
+ const loaded = await readPackage(bytes);
124
+ const checks = staticChecks(loaded.manifest, loaded.paths, options.engine);
125
+ const base = { artifact, sha256, browser: options.engine, limits: LIMITS };
126
+ let engineChecks;
127
+ if (checks.some((c) => c.status === 'failed')) {
128
+ // A package that cannot load is reported as such, without a browser run
129
+ // that would only fail later with a vaguer message.
130
+ engineChecks = { engine: { name: options.engine }, checks: [] };
131
+ }
132
+ else if (options.engine === 'firefox') {
133
+ engineChecks = await smokeFirefox(artifact, loaded.manifest, options);
134
+ }
135
+ else {
136
+ engineChecks = await smokeChromium(loaded, options);
137
+ }
138
+ const all = [...checks, ...engineChecks.checks];
139
+ return {
140
+ ...base,
141
+ engine: engineChecks.engine,
142
+ ...(engineChecks.extensionId ? { extensionId: engineChecks.extensionId } : {}),
143
+ status: all.some((c) => c.status === 'failed') ? 'failed' : 'passed',
144
+ checks: all,
145
+ };
146
+ }
147
+ // ── Chromium / Edge ─────────────────────────────────────────────────────────
148
+ const PLAYWRIGHT_HELP = 'Chromium and Edge smoke tests use Playwright, which the CLI does not install for you. ' +
149
+ 'In your project: npm i -D playwright && npx playwright install chromium ' +
150
+ '(Edge: install Microsoft Edge; Playwright drives it through the msedge channel).';
151
+ /** Resolve Playwright from the project first, then next to the CLI (global installs, CI tool prefixes). */
152
+ export async function loadPlaywright(cwd = process.cwd()) {
153
+ const bases = [path.join(cwd, 'package.json'), fileURLToPath(import.meta.url)];
154
+ for (const base of bases) {
155
+ const require = createRequire(base);
156
+ for (const name of ['playwright', 'playwright-core', '@playwright/test']) {
157
+ let resolved;
158
+ try {
159
+ resolved = require.resolve(name);
160
+ }
161
+ catch {
162
+ continue;
163
+ }
164
+ const mod = await import(pathToFileURL(resolved).href);
165
+ const chromium = mod.chromium ?? mod.default?.chromium;
166
+ if (!chromium)
167
+ continue;
168
+ let version;
169
+ try {
170
+ version = require(`${name}/package.json`).version;
171
+ }
172
+ catch {
173
+ // Some exports maps hide package.json; the version is informational.
174
+ }
175
+ return { chromium, version };
176
+ }
177
+ }
178
+ throw new InvalidInputError(PLAYWRIGHT_HELP);
179
+ }
180
+ async function extractZip(zip, dir) {
181
+ for (const file of Object.values(zip.files)) {
182
+ // Refuse anything that would land outside the extraction directory.
183
+ const target = path.resolve(dir, file.name);
184
+ if (!target.startsWith(`${path.resolve(dir)}${path.sep}`))
185
+ throw new InvalidInputError(`Unsafe zip entry: ${file.name}`);
186
+ if (file.dir) {
187
+ fs.mkdirSync(target, { recursive: true });
188
+ continue;
189
+ }
190
+ fs.mkdirSync(path.dirname(target), { recursive: true });
191
+ fs.writeFileSync(target, await file.async('nodebuffer'));
192
+ }
193
+ }
194
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
195
+ async function until(fn, timeoutMs) {
196
+ const end = Date.now() + timeoutMs;
197
+ for (;;) {
198
+ const value = await fn().catch(() => undefined);
199
+ if (value)
200
+ return value;
201
+ if (Date.now() > end)
202
+ return undefined;
203
+ await sleep(250);
204
+ }
205
+ }
206
+ async function smokeChromium(loaded, options) {
207
+ const timeout = options.timeoutMs ?? 15_000;
208
+ const { chromium, version } = await loadPlaywright(options.cwd);
209
+ const channel = options.engine === 'edge' ? 'msedge' : 'chromium';
210
+ const extDir = fs.mkdtempSync(path.join(os.tmpdir(), 'extenshi-smoke-ext-'));
211
+ const profile = fs.mkdtempSync(path.join(os.tmpdir(), 'extenshi-smoke-profile-'));
212
+ const checks = [];
213
+ let context;
214
+ try {
215
+ await extractZip(loaded.zip, extDir);
216
+ try {
217
+ context = await chromium.launchPersistentContext(profile, {
218
+ channel,
219
+ headless: !options.headed,
220
+ ...(options.browserPath ? { executablePath: options.browserPath } : {}),
221
+ args: [`--disable-extensions-except=${extDir}`, `--load-extension=${extDir}`],
222
+ });
223
+ }
224
+ catch (error) {
225
+ const message = error.message.split('\n')[0];
226
+ throw new InvalidInputError(`Could not start ${channel === 'msedge' ? 'Microsoft Edge' : 'Chromium'}: ${message}. ${channel === 'msedge'
227
+ ? 'Install Microsoft Edge (or npx playwright install msedge).'
228
+ : 'Run: npx playwright install chromium'}`);
229
+ }
230
+ const engine = {
231
+ name: 'playwright',
232
+ version,
233
+ channel,
234
+ browserVersion: context.browser()?.version?.(),
235
+ };
236
+ const admin = await context.newPage();
237
+ await admin.goto('chrome://extensions');
238
+ const info = async () => admin.evaluate(() => new Promise((resolve) => globalThis.chrome.developerPrivate.getExtensionsInfo({ includeDisabled: true, includeTerminated: true }, resolve)));
239
+ const find = async () => (await info()).find((e) => e.location === 'UNPACKED');
240
+ const ext = await until(find, timeout);
241
+ if (!ext) {
242
+ checks.push({
243
+ name: 'extension loads',
244
+ status: 'failed',
245
+ detail: `${channel === 'msedge' ? 'Edge' : 'Chromium'} did not load the package (it rejects manifests with errors).`,
246
+ });
247
+ return { engine, checks };
248
+ }
249
+ const id = ext.id;
250
+ checks.push({
251
+ name: 'extension loads',
252
+ status: ext.state === 'ENABLED' ? 'passed' : 'failed',
253
+ detail: ext.state,
254
+ });
255
+ // Errors are collected only in developer mode, and only for what happens
256
+ // after it is on — so switch it on and reload the extension once.
257
+ const reload = await admin.evaluate((extensionId) => new Promise((resolve) => {
258
+ const dp = globalThis.chrome.developerPrivate;
259
+ dp.updateProfileConfiguration({ inDeveloperMode: true }, () => dp.reload(extensionId, { failQuietly: true, populateErrorForUnpacked: true }, (loadError) => resolve(loadError ?? null)));
260
+ }), id);
261
+ if (reload) {
262
+ checks.push({
263
+ name: 'extension reloads',
264
+ status: 'failed',
265
+ detail: JSON.stringify(reload).slice(0, 500),
266
+ });
267
+ return { engine, extensionId: id, checks };
268
+ }
269
+ const background = loaded.manifest.background ?? {};
270
+ const workerPath = typeof background.service_worker === 'string' ? background.service_worker.replace(/^\.?\/+/, '') : null;
271
+ const pagePath = typeof background.page === 'string' ? background.page.replace(/^\.?\/+/, '') : null;
272
+ const expected = workerPath ?? pagePath ?? (Array.isArray(background.scripts) ? '_generated_background_page.html' : null);
273
+ if (expected) {
274
+ const url = `chrome-extension://${id}/${expected}`;
275
+ const running = await until(async () => {
276
+ const current = (await info()).find((e) => e.id === id);
277
+ return current?.views?.some((v) => v.url === url);
278
+ }, timeout);
279
+ checks.push({
280
+ name: workerPath ? 'service worker starts' : 'background page starts',
281
+ status: running ? 'passed' : 'failed',
282
+ detail: running ? url : `${url} did not start within ${timeout} ms`,
283
+ });
284
+ }
285
+ else {
286
+ checks.push({
287
+ name: 'service worker starts',
288
+ status: 'skipped',
289
+ detail: 'the manifest declares no background',
290
+ });
291
+ }
292
+ for (const page of extensionPages(loaded.manifest)) {
293
+ const tab = await context.newPage();
294
+ const errors = [];
295
+ tab.on('pageerror', (error) => errors.push(`uncaught: ${error.message}`));
296
+ tab.on('console', (message) => {
297
+ if (message.type() === 'error')
298
+ errors.push(`console.error: ${message.text()}`);
299
+ });
300
+ const url = `chrome-extension://${id}/${page.path}`;
301
+ try {
302
+ await tab.goto(url, { waitUntil: 'load', timeout });
303
+ await sleep(Math.min(1_500, timeout));
304
+ }
305
+ catch (error) {
306
+ errors.push(`did not open: ${error.message.split('\n')[0]}`);
307
+ }
308
+ checks.push({
309
+ name: `${page.role} page opens without console errors`,
310
+ status: errors.length ? 'failed' : 'passed',
311
+ detail: errors.length ? `${page.path}: ${errors.slice(0, 5).join(' | ')}` : page.path,
312
+ });
313
+ await tab.close();
314
+ }
315
+ const final = (await info()).find((e) => e.id === id) ?? {};
316
+ const manifestProblems = [
317
+ ...(final.manifestErrors ?? []).map((e) => String(e.message)),
318
+ ...(final.installWarnings ?? []).map(String),
319
+ ];
320
+ checks.push({
321
+ name: 'no manifest errors',
322
+ status: manifestProblems.length ? 'failed' : 'passed',
323
+ ...(manifestProblems.length ? { detail: manifestProblems.slice(0, 10).join(' | ') } : {}),
324
+ });
325
+ const runtime = (final.runtimeErrors ?? []).map((e) => `${e.message}${e.source ? ` (${e.source})` : ''}`);
326
+ checks.push({
327
+ name: 'no runtime errors',
328
+ status: runtime.length ? 'failed' : 'passed',
329
+ ...(runtime.length ? { detail: runtime.slice(0, 10).join(' | ') } : {}),
330
+ });
331
+ return { engine, extensionId: id, checks };
332
+ }
333
+ finally {
334
+ await context?.close().catch(() => { });
335
+ fs.rmSync(extDir, { recursive: true, force: true });
336
+ fs.rmSync(profile, { recursive: true, force: true });
337
+ }
338
+ }
339
+ // ── Firefox ─────────────────────────────────────────────────────────────────
340
+ async function smokeFirefox(artifact, manifest, options) {
341
+ const timeout = options.timeoutMs ?? 15_000;
342
+ const binary = findFirefox(options.firefoxBinary);
343
+ if (!binary)
344
+ throw new InvalidInputError('No Firefox found. Install Firefox, or point at a binary with --firefox-bin <path> (or FIREFOX_BIN).');
345
+ const addonId = manifestGeckoId(manifest);
346
+ const uuid = randomUUID();
347
+ const base = `moz-extension://${uuid}/`;
348
+ const firefox = await launchFirefox({
349
+ binary,
350
+ uuids: { [addonId]: uuid },
351
+ headless: !options.headed,
352
+ timeoutMs: timeout * 2,
353
+ });
354
+ const checks = [];
355
+ const engine = { name: 'firefox-rdp', binary };
356
+ try {
357
+ const { client } = firefox;
358
+ // Every document of the add-on reports here once the watcher is attached.
359
+ const windows = new Map();
360
+ const errors = [];
361
+ client.on((packet) => {
362
+ if (packet.type === 'target-available-form' && packet.target?.innerWindowId)
363
+ windows.set(packet.target.innerWindowId, packet.target.url);
364
+ if (packet.type !== 'resources-available-array')
365
+ return;
366
+ for (const [kind, resources] of packet.array ?? []) {
367
+ for (const resource of resources ?? []) {
368
+ if (kind === 'error-message' && resource.pageError?.error && !resource.pageError.warning)
369
+ errors.push({
370
+ window: resource.pageError.innerWindowID,
371
+ url: resource.pageError.sourceName,
372
+ text: `uncaught: ${resource.pageError.errorMessage}`,
373
+ });
374
+ if (kind === 'console-message' && resource.level === 'error')
375
+ errors.push({
376
+ window: resource.innerWindowID,
377
+ url: resource.filename,
378
+ text: `console.error: ${(resource.arguments ?? []).map((a) => (typeof a === 'string' ? a : JSON.stringify(a))).join(' ')}`,
379
+ });
380
+ }
381
+ }
382
+ });
383
+ const root = await client.request('root', 'getRoot');
384
+ if (root.deviceActor) {
385
+ const device = await client.request(root.deviceActor, 'getDescription').catch(() => null);
386
+ const version = device?.value?.version;
387
+ if (typeof version === 'string')
388
+ engine.browserVersion = version;
389
+ }
390
+ const installed = await client.request(root.addonsActor, 'installTemporaryAddon', { addonPath: artifact });
391
+ if (installed.error) {
392
+ checks.push({
393
+ name: 'temporary install accepted',
394
+ status: 'failed',
395
+ detail: String(installed.message ?? installed.error),
396
+ });
397
+ return { engine, checks };
398
+ }
399
+ checks.push({ name: 'temporary install accepted', status: 'passed', detail: installed.addon?.id });
400
+ const find = async () => (await client.request('root', 'listAddons')).addons?.find((a) => a.id === addonId);
401
+ const addon = await until(find, timeout);
402
+ if (!addon) {
403
+ checks.push({
404
+ name: 'add-on is listed',
405
+ status: 'failed',
406
+ detail: `${addonId} is not listed after install`,
407
+ });
408
+ return { engine, extensionId: addonId, checks };
409
+ }
410
+ const watcher = await client.request(addon.actor, 'getWatcher', {});
411
+ if (watcher.actor) {
412
+ await client.request(watcher.actor, 'watchTargets', { targetType: 'frame' });
413
+ await client.request(watcher.actor, 'watchResources', {
414
+ resourceTypes: ['error-message', 'console-message'],
415
+ });
416
+ }
417
+ const bg = manifest.background ?? {};
418
+ if (bg.scripts || bg.page || bg.service_worker) {
419
+ const running = await until(async () => (await find())?.backgroundScriptStatus === 'RUNNING', timeout);
420
+ const status = (await find())?.backgroundScriptStatus;
421
+ checks.push(status === undefined
422
+ ? {
423
+ name: 'background starts',
424
+ status: 'skipped',
425
+ detail: 'this Firefox does not report background status',
426
+ }
427
+ : { name: 'background starts', status: running ? 'passed' : 'failed', detail: String(status) });
428
+ }
429
+ else {
430
+ checks.push({
431
+ name: 'background starts',
432
+ status: 'skipped',
433
+ detail: 'the manifest declares no background',
434
+ });
435
+ }
436
+ const warnings = ((await find())?.warnings ?? []);
437
+ checks.push({
438
+ name: 'no manifest warnings',
439
+ status: warnings.length ? 'failed' : 'passed',
440
+ ...(warnings.length ? { detail: warnings.map(String).slice(0, 10).join(' | ') } : {}),
441
+ });
442
+ const tabs = await client.request('root', 'listTabs');
443
+ const tab = tabs.tabs?.[0];
444
+ for (const page of extensionPages(manifest)) {
445
+ const url = `${base}${page.path}`;
446
+ const before = errors.length;
447
+ let problem;
448
+ if (!tab)
449
+ problem = 'no browser tab to open it in';
450
+ else {
451
+ const target = await client.request(tab.actor, 'getTarget');
452
+ const form = target.frame ?? target;
453
+ await client.request(form.actor, 'navigateTo', { url });
454
+ await sleep(Math.min(2_000, timeout));
455
+ const after = await client.request(tab.actor, 'getTarget');
456
+ const loadedUrl = (after.frame ?? after).url;
457
+ if (loadedUrl !== url)
458
+ problem = `did not open (landed on ${loadedUrl})`;
459
+ }
460
+ const pageErrors = errors
461
+ .slice(before)
462
+ .filter((e) => (e.window ? windows.get(e.window) === url : e.url?.startsWith(base)));
463
+ const problems = [...(problem ? [problem] : []), ...pageErrors.map((e) => e.text)];
464
+ checks.push({
465
+ name: `${page.role} page opens without console errors`,
466
+ status: problems.length ? 'failed' : 'passed',
467
+ detail: problems.length ? `${page.path}: ${problems.slice(0, 5).join(' | ')}` : page.path,
468
+ });
469
+ }
470
+ await sleep(250);
471
+ const runtime = errors.map((e) => `${e.text}${e.url ? ` (${e.url.replace(base, '')})` : ''}`);
472
+ checks.push({
473
+ name: 'no runtime errors',
474
+ status: runtime.length ? 'failed' : 'passed',
475
+ ...(runtime.length ? { detail: [...new Set(runtime)].slice(0, 10).join(' | ') } : {}),
476
+ });
477
+ return { engine, extensionId: addonId, checks };
478
+ }
479
+ finally {
480
+ await firefox.close();
481
+ }
482
+ }
483
+ export function renderSmoke(result) {
484
+ const mark = { passed: '✓', failed: '✗', skipped: '–' };
485
+ return [
486
+ `${result.browser} smoke — ${result.status.toUpperCase()} ${result.sha256} ${result.artifact}`,
487
+ ...result.checks.map((c) => ` ${mark[c.status]} ${c.name}${c.detail ? ` — ${c.detail}` : ''}`),
488
+ ...result.limits.map((l) => ` note: ${l}`),
489
+ ].join('\n');
490
+ }
491
+ //# sourceMappingURL=smoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smoke.js","sourceRoot":"","sources":["../src/smoke.ts"],"names":[],"mappings":"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"}