@playdrop/playdrop-cli 0.13.17 → 0.14.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/config/client-meta.json +2 -2
- package/dist/apps/loadCheck.d.ts +2 -21
- package/dist/apps/loadCheck.js +22 -106
- package/dist/apps/surfaceProfiles.d.ts +1 -0
- package/dist/apps/surfaceProfiles.js +5 -4
- package/dist/apps/validate.d.ts +1 -1
- package/dist/apps/validate.js +2 -420
- package/dist/catalogue.js +32 -1
- package/dist/commands/captureListing.d.ts +22 -0
- package/dist/commands/captureListing.js +216 -7
- package/dist/commands/check.d.ts +11 -1
- package/dist/commands/check.js +19 -39
- package/dist/commands/detail.js +35 -2
- package/dist/commands/review.d.ts +11 -1
- package/dist/commands/review.js +20 -13
- package/dist/commands/upload.d.ts +1 -7
- package/dist/commands/upload.js +20 -462
- package/dist/commands/validate.js +0 -3
- package/dist/commands/worker.d.ts +1 -3
- package/dist/commands/worker.js +43 -39
- package/dist/index.js +2 -4
- package/dist/listingPreflight.d.ts +3 -0
- package/dist/listingPreflight.js +48 -24
- package/node_modules/@playdrop/config/client-meta.json +2 -2
- package/node_modules/@playdrop/types/dist/app-playtest-tape.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/app-playtest-tape.js +23 -15
- package/package.json +1 -1
package/config/client-meta.json
CHANGED
package/dist/apps/loadCheck.d.ts
CHANGED
|
@@ -30,32 +30,14 @@ export type HostedLaunchState = {
|
|
|
30
30
|
errorCode: string | null;
|
|
31
31
|
message: string | null;
|
|
32
32
|
};
|
|
33
|
-
export
|
|
34
|
-
|
|
35
|
-
x: number;
|
|
36
|
-
y: number;
|
|
37
|
-
button?: 'left' | 'right' | 'middle';
|
|
38
|
-
} | {
|
|
39
|
-
type: 'press';
|
|
40
|
-
key: string;
|
|
41
|
-
} | {
|
|
42
|
-
type: 'wait';
|
|
43
|
-
ms: number;
|
|
44
|
-
};
|
|
33
|
+
export declare function formatConsoleValue(value: unknown): string;
|
|
34
|
+
export declare function formatBrowserConsoleMessage(values: unknown[], fallbackText: string): string;
|
|
45
35
|
export declare function resolveLoadCheckSurface(surfaceTargets: unknown, primarySurface?: unknown): AppSurface;
|
|
46
36
|
export declare function cloneLoadCheckContextOptions(surface: AppSurface): BrowserContextOptions;
|
|
47
37
|
export declare function isSoftwareWebGlRenderer(renderer: string | null | undefined): boolean;
|
|
48
|
-
export declare function normalizeProjectCheckActions(value: unknown): ProjectCheckAction[];
|
|
49
|
-
export declare function focusProjectCheckGameFrame(page: Pick<Page, 'mouse'>, frame: Frame): Promise<{
|
|
50
|
-
x: number;
|
|
51
|
-
y: number;
|
|
52
|
-
width: number;
|
|
53
|
-
height: number;
|
|
54
|
-
}>;
|
|
55
38
|
export declare function dispatchPlaytestTapeToFrame(page: Page, frame: Frame, surface: AppSurface, tape: AppPlaytestTape, hooks?: {
|
|
56
39
|
onBeforeEvent?: (eventIndex: number, event: AppPlaytestTapeEvent) => void;
|
|
57
40
|
}): Promise<void>;
|
|
58
|
-
export declare function dispatchProjectCheckActionsToFrame(page: Page, frame: Frame, actions: readonly ProjectCheckAction[]): Promise<void>;
|
|
59
41
|
export declare function formatHostedLoadCheckFailure(taskName: string, result: HostedLoadCheckResult, scope?: 'local' | 'staged' | 'final'): string;
|
|
60
42
|
export declare function redactHostedLoadCheckSecrets(text: string, sourceUrl: string): string;
|
|
61
43
|
export declare function runLocalHostedLoadCheck(input: {
|
|
@@ -71,7 +53,6 @@ export declare function runLocalHostedLoadCheck(input: {
|
|
|
71
53
|
captureSession?: TaskCaptureSession | null;
|
|
72
54
|
allowUnregisteredViewerLaunch?: boolean;
|
|
73
55
|
screenshotPath?: string | null;
|
|
74
|
-
actions?: ProjectCheckAction[];
|
|
75
56
|
surface?: AppSurface;
|
|
76
57
|
playtestTape?: AppPlaytestTape;
|
|
77
58
|
postReadyWaitMs?: number;
|
package/dist/apps/loadCheck.js
CHANGED
|
@@ -4,13 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.PLAYDROP_SURFACE_CONTEXT_OPTIONS = void 0;
|
|
7
|
+
exports.formatConsoleValue = formatConsoleValue;
|
|
8
|
+
exports.formatBrowserConsoleMessage = formatBrowserConsoleMessage;
|
|
7
9
|
exports.resolveLoadCheckSurface = resolveLoadCheckSurface;
|
|
8
10
|
exports.cloneLoadCheckContextOptions = cloneLoadCheckContextOptions;
|
|
9
11
|
exports.isSoftwareWebGlRenderer = isSoftwareWebGlRenderer;
|
|
10
|
-
exports.normalizeProjectCheckActions = normalizeProjectCheckActions;
|
|
11
|
-
exports.focusProjectCheckGameFrame = focusProjectCheckGameFrame;
|
|
12
12
|
exports.dispatchPlaytestTapeToFrame = dispatchPlaytestTapeToFrame;
|
|
13
|
-
exports.dispatchProjectCheckActionsToFrame = dispatchProjectCheckActionsToFrame;
|
|
14
13
|
exports.formatHostedLoadCheckFailure = formatHostedLoadCheckFailure;
|
|
15
14
|
exports.redactHostedLoadCheckSecrets = redactHostedLoadCheckSecrets;
|
|
16
15
|
exports.runLocalHostedLoadCheck = runLocalHostedLoadCheck;
|
|
@@ -37,7 +36,6 @@ var surfaceProfiles_2 = require("./surfaceProfiles");
|
|
|
37
36
|
Object.defineProperty(exports, "PLAYDROP_SURFACE_CONTEXT_OPTIONS", { enumerable: true, get: function () { return surfaceProfiles_2.PLAYDROP_SURFACE_CONTEXT_OPTIONS; } });
|
|
38
37
|
const FRAME_SELECTOR = 'iframe[title="Game"]';
|
|
39
38
|
const DEFAULT_HOSTED_LOAD_TIMEOUT_MS = 15000;
|
|
40
|
-
const POST_READY_SETTLE_MS = 750;
|
|
41
39
|
const PLAYTEST_INTERACTIVE_MEAN_DELTA_MIN = 0.002;
|
|
42
40
|
const PLAYTEST_INTERACTIVE_CHANGED_PIXEL_RATIO_MIN = 0.01;
|
|
43
41
|
const LOAD_CHECK_SURFACE_ORDER = ['DESKTOP', 'MOBILE_LANDSCAPE', 'MOBILE_PORTRAIT'];
|
|
@@ -75,6 +73,9 @@ function isKnownGoogleTelemetryUrl(rawUrl) {
|
|
|
75
73
|
return GOOGLE_TELEMETRY_HOSTS.some((domain) => isHostOrSubdomain(hostname, domain));
|
|
76
74
|
}
|
|
77
75
|
function formatConsoleValue(value) {
|
|
76
|
+
if (value instanceof Error) {
|
|
77
|
+
return `${value.name}: ${value.message}`;
|
|
78
|
+
}
|
|
78
79
|
if (typeof value === 'string')
|
|
79
80
|
return value;
|
|
80
81
|
if (typeof value === 'number' || typeof value === 'boolean' || value === null) {
|
|
@@ -84,6 +85,10 @@ function formatConsoleValue(value) {
|
|
|
84
85
|
return 'undefined';
|
|
85
86
|
}
|
|
86
87
|
if (typeof value === 'object') {
|
|
88
|
+
const namedError = value;
|
|
89
|
+
if (typeof namedError.message === 'string') {
|
|
90
|
+
return `${typeof namedError.name === 'string' ? `${namedError.name}: ` : ''}${namedError.message}`;
|
|
91
|
+
}
|
|
87
92
|
try {
|
|
88
93
|
return JSON.stringify(value);
|
|
89
94
|
}
|
|
@@ -93,6 +98,13 @@ function formatConsoleValue(value) {
|
|
|
93
98
|
}
|
|
94
99
|
return String(value);
|
|
95
100
|
}
|
|
101
|
+
function formatBrowserConsoleMessage(values, fallbackText) {
|
|
102
|
+
if (values.length === 0) {
|
|
103
|
+
return fallbackText;
|
|
104
|
+
}
|
|
105
|
+
const rendered = values.map(formatConsoleValue).join(' ');
|
|
106
|
+
return rendered === '{}' || rendered === '[object]' ? fallbackText : rendered;
|
|
107
|
+
}
|
|
96
108
|
function serializePayload(payload) {
|
|
97
109
|
if (payload === undefined) {
|
|
98
110
|
return '';
|
|
@@ -263,67 +275,6 @@ function isSoftwareWebGlRenderer(renderer) {
|
|
|
263
275
|
const normalized = typeof renderer === 'string' ? renderer.trim() : '';
|
|
264
276
|
return normalized.length > 0 && SOFTWARE_WEBGL_RENDERER_PATTERNS.some((pattern) => pattern.test(normalized));
|
|
265
277
|
}
|
|
266
|
-
function normalizeProjectCheckActions(value) {
|
|
267
|
-
if (value === undefined || value === null) {
|
|
268
|
-
return [];
|
|
269
|
-
}
|
|
270
|
-
if (!Array.isArray(value)) {
|
|
271
|
-
throw new Error('project_check_actions_invalid: expected a JSON array.');
|
|
272
|
-
}
|
|
273
|
-
return value.map((entry, index) => {
|
|
274
|
-
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
|
|
275
|
-
throw new Error(`project_check_action_invalid:${index}`);
|
|
276
|
-
}
|
|
277
|
-
const type = typeof entry.type === 'string'
|
|
278
|
-
? entry.type.trim().toLowerCase()
|
|
279
|
-
: '';
|
|
280
|
-
if (type === 'click') {
|
|
281
|
-
const x = Number(entry.x);
|
|
282
|
-
const y = Number(entry.y);
|
|
283
|
-
if (!Number.isFinite(x) || !Number.isFinite(y)) {
|
|
284
|
-
throw new Error(`project_check_action_invalid:${index}:click_coordinates_required`);
|
|
285
|
-
}
|
|
286
|
-
const rawButton = typeof entry.button === 'string'
|
|
287
|
-
? entry.button.trim().toLowerCase()
|
|
288
|
-
: '';
|
|
289
|
-
const button = rawButton === 'right' || rawButton === 'middle' ? rawButton : 'left';
|
|
290
|
-
return { type: 'click', x, y, button };
|
|
291
|
-
}
|
|
292
|
-
if (type === 'press') {
|
|
293
|
-
const key = typeof entry.key === 'string'
|
|
294
|
-
? entry.key.trim()
|
|
295
|
-
: '';
|
|
296
|
-
if (!key) {
|
|
297
|
-
throw new Error(`project_check_action_invalid:${index}:key_required`);
|
|
298
|
-
}
|
|
299
|
-
return { type: 'press', key };
|
|
300
|
-
}
|
|
301
|
-
if (type === 'wait') {
|
|
302
|
-
const ms = Number(entry.ms);
|
|
303
|
-
if (!Number.isInteger(ms) || ms < 0 || ms > 60000) {
|
|
304
|
-
throw new Error(`project_check_action_invalid:${index}:wait_ms_invalid`);
|
|
305
|
-
}
|
|
306
|
-
return { type: 'wait', ms };
|
|
307
|
-
}
|
|
308
|
-
throw new Error(`project_check_action_type_unknown:${index}`);
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
async function focusProjectCheckGameFrame(page, frame) {
|
|
312
|
-
const element = await frame.frameElement();
|
|
313
|
-
try {
|
|
314
|
-
await element.scrollIntoViewIfNeeded().catch(() => { });
|
|
315
|
-
const box = await element.boundingBox();
|
|
316
|
-
if (!box) {
|
|
317
|
-
throw new Error('project_check_game_frame_not_visible');
|
|
318
|
-
}
|
|
319
|
-
await page.mouse.click(box.x + (box.width / 2), box.y + (box.height / 2), { button: 'left' });
|
|
320
|
-
await frame.evaluate(() => window.focus()).catch(() => { });
|
|
321
|
-
return box;
|
|
322
|
-
}
|
|
323
|
-
finally {
|
|
324
|
-
await element.dispose().catch(() => { });
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
278
|
async function prepareProjectCheckGameFrame(frame) {
|
|
328
279
|
const element = await frame.frameElement();
|
|
329
280
|
try {
|
|
@@ -457,24 +408,6 @@ async function dispatchPlaytestTapeToFrame(page, frame, surface, tape, hooks = {
|
|
|
457
408
|
}
|
|
458
409
|
}
|
|
459
410
|
}
|
|
460
|
-
async function dispatchProjectCheckActionsToFrame(page, frame, actions) {
|
|
461
|
-
for (const action of actions) {
|
|
462
|
-
if (action.type === 'wait') {
|
|
463
|
-
await page.waitForTimeout(action.ms);
|
|
464
|
-
continue;
|
|
465
|
-
}
|
|
466
|
-
const box = await focusProjectCheckGameFrame(page, frame);
|
|
467
|
-
if (action.type === 'click') {
|
|
468
|
-
await page.mouse.click(box.x + action.x, box.y + action.y, { button: action.button ?? 'left' });
|
|
469
|
-
continue;
|
|
470
|
-
}
|
|
471
|
-
if (action.type === 'press') {
|
|
472
|
-
await page.keyboard.press(action.key);
|
|
473
|
-
continue;
|
|
474
|
-
}
|
|
475
|
-
throw new Error('project_check_action_type_unknown');
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
411
|
async function findGameFrame(page, timeoutMs) {
|
|
479
412
|
const handle = await page.waitForSelector(FRAME_SELECTOR, { timeout: timeoutMs });
|
|
480
413
|
const frame = await handle.contentFrame();
|
|
@@ -514,7 +447,6 @@ async function saveScreenshot(page, screenshotPath) {
|
|
|
514
447
|
}
|
|
515
448
|
await (0, promises_1.mkdir)((0, node_path_1.dirname)(normalizedPath), { recursive: true });
|
|
516
449
|
await page.screenshot({ path: normalizedPath, fullPage: true });
|
|
517
|
-
console.log(`[check] Saved screenshot to ${(0, node_path_1.relative)(process.cwd(), normalizedPath) || normalizedPath}`);
|
|
518
450
|
return normalizedPath;
|
|
519
451
|
}
|
|
520
452
|
async function saveGameFrameScreenshot(page, screenshotPath) {
|
|
@@ -637,9 +569,11 @@ async function runHostedLoadCheck(options) {
|
|
|
637
569
|
settleHostedLaunchWaiter(normalizedHostedState);
|
|
638
570
|
}
|
|
639
571
|
}
|
|
640
|
-
const
|
|
641
|
-
|
|
642
|
-
|
|
572
|
+
const normalizedType = typeof type === 'string' ? type.toLowerCase() : 'info';
|
|
573
|
+
if (/error|failed|denied|unreachable/.test(normalizedType)) {
|
|
574
|
+
const serialized = serializePayload(payload);
|
|
575
|
+
errors.push(redactReportText(['[check][custom]', normalizedType, serialized].filter(Boolean).join(' ')));
|
|
576
|
+
}
|
|
643
577
|
});
|
|
644
578
|
await page.addInitScript(() => {
|
|
645
579
|
window.addEventListener('unhandledrejection', (event) => {
|
|
@@ -676,14 +610,11 @@ async function runHostedLoadCheck(options) {
|
|
|
676
610
|
const handleConsoleMessage = async (message) => {
|
|
677
611
|
const type = message.type();
|
|
678
612
|
const args = await Promise.all(message.args().map((arg) => arg.jsonValue().catch(() => arg.toString())));
|
|
679
|
-
const rendered = args
|
|
613
|
+
const rendered = formatBrowserConsoleMessage(args, message.text());
|
|
680
614
|
const line = redactReportText(withTapeAction(`[check][console:${type}] ${rendered}`));
|
|
681
615
|
if (type === 'error' || type === 'assert' || type === 'trace') {
|
|
682
616
|
errors.push(line);
|
|
683
|
-
console.error(line);
|
|
684
|
-
return;
|
|
685
617
|
}
|
|
686
|
-
console.log(line);
|
|
687
618
|
};
|
|
688
619
|
page.on('console', (message) => {
|
|
689
620
|
void handleConsoleMessage(message).catch((error) => {
|
|
@@ -695,7 +626,6 @@ async function runHostedLoadCheck(options) {
|
|
|
695
626
|
const text = redactReportText(error?.message ?? String(error));
|
|
696
627
|
const line = withTapeAction(`[check][pageerror] ${text}`);
|
|
697
628
|
errors.push(line);
|
|
698
|
-
console.error(line);
|
|
699
629
|
});
|
|
700
630
|
page.on('requestfailed', (request) => {
|
|
701
631
|
const failure = request.failure();
|
|
@@ -710,7 +640,6 @@ async function runHostedLoadCheck(options) {
|
|
|
710
640
|
}
|
|
711
641
|
const line = withTapeAction(`[check][requestfailed] ${text}`);
|
|
712
642
|
errors.push(line);
|
|
713
|
-
console.error(line);
|
|
714
643
|
});
|
|
715
644
|
page.on('response', (response) => {
|
|
716
645
|
const status = response.status();
|
|
@@ -724,9 +653,7 @@ async function runHostedLoadCheck(options) {
|
|
|
724
653
|
}
|
|
725
654
|
const line = withTapeAction(`[check][response] ${text}`);
|
|
726
655
|
errors.push(line);
|
|
727
|
-
console.error(line);
|
|
728
656
|
});
|
|
729
|
-
console.log(`[check] Opening ${reportTargetUrl}`);
|
|
730
657
|
const response = await page.goto(options.targetUrl, { waitUntil: 'domcontentloaded', timeout: 30000 });
|
|
731
658
|
if (response && !response.ok()) {
|
|
732
659
|
errors.push(`[check][navigation] ${response.status()} ${response.statusText()} ${reportTargetUrl}`);
|
|
@@ -764,14 +691,10 @@ async function runHostedLoadCheck(options) {
|
|
|
764
691
|
}
|
|
765
692
|
const frame = await findGameFrame(page, readinessTimeoutMs);
|
|
766
693
|
webglRenderer = await readWebGlRenderer(frame);
|
|
767
|
-
console.log(`[check] WebGL renderer: ${webglRenderer}`);
|
|
768
694
|
if (isSoftwareWebGlRenderer(webglRenderer)) {
|
|
769
695
|
throw new Error(`project_check_webgl_renderer_software: WebGL renderer is "${webglRenderer}". Real hardware acceleration is required.`);
|
|
770
696
|
}
|
|
771
697
|
await saveGameFrameScreenshot(page, options.readyGameFrameScreenshotPath);
|
|
772
|
-
if (options.playtestTape && options.actions?.length) {
|
|
773
|
-
throw new Error('project_check_input_mode_conflict: playtest tape and legacy actions cannot run together.');
|
|
774
|
-
}
|
|
775
698
|
if (options.playtestTape) {
|
|
776
699
|
if (!options.playtestSurface) {
|
|
777
700
|
throw new Error('project_check_playtest_surface_required');
|
|
@@ -782,10 +705,6 @@ async function runHostedLoadCheck(options) {
|
|
|
782
705
|
},
|
|
783
706
|
});
|
|
784
707
|
}
|
|
785
|
-
else if (options.actions?.length) {
|
|
786
|
-
await dispatchProjectCheckActionsToFrame(page, frame, options.actions);
|
|
787
|
-
await page.waitForTimeout(POST_READY_SETTLE_MS);
|
|
788
|
-
}
|
|
789
708
|
else if (options.postReadyWaitMs && options.postReadyWaitMs > 0) {
|
|
790
709
|
await page.waitForTimeout(options.postReadyWaitMs);
|
|
791
710
|
}
|
|
@@ -916,7 +835,6 @@ async function runLocalHostedLoadCheck(input) {
|
|
|
916
835
|
expectedHostedLaunchState: resolvePostAuthHostedLaunchState(localAppMetadata.controllerMode),
|
|
917
836
|
contextOptions,
|
|
918
837
|
screenshotPath: input.screenshotPath,
|
|
919
|
-
actions: input.actions,
|
|
920
838
|
playtestTape: input.playtestTape,
|
|
921
839
|
playtestSurface: captureSurface,
|
|
922
840
|
postReadyWaitMs: input.postReadyWaitMs,
|
|
@@ -962,7 +880,6 @@ async function runLocalHostedLoadCheck(input) {
|
|
|
962
880
|
savedSessionBootstrap: true,
|
|
963
881
|
contextOptions,
|
|
964
882
|
screenshotPath: input.screenshotPath,
|
|
965
|
-
actions: input.actions,
|
|
966
883
|
playtestTape: input.playtestTape,
|
|
967
884
|
playtestSurface: captureSurface,
|
|
968
885
|
postReadyWaitMs: input.postReadyWaitMs,
|
|
@@ -981,7 +898,6 @@ async function runLocalHostedLoadCheck(input) {
|
|
|
981
898
|
expectedHostedLaunchState: anonymousExpectedState,
|
|
982
899
|
contextOptions,
|
|
983
900
|
screenshotPath: input.screenshotPath,
|
|
984
|
-
actions: input.actions,
|
|
985
901
|
playtestTape: input.playtestTape,
|
|
986
902
|
playtestSurface: captureSurface,
|
|
987
903
|
postReadyWaitMs: input.postReadyWaitMs,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AppSurface } from '@playdrop/types';
|
|
2
2
|
import type { BrowserContextOptions } from 'playwright-core';
|
|
3
|
+
export declare const PLAYDROP_MOBILE_USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 26_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1";
|
|
3
4
|
export type PlaydropSurfaceProfile = {
|
|
4
5
|
contextOptions: BrowserContextOptions;
|
|
5
6
|
playwrightMcpDevice: string | null;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PLAYDROP_SURFACE_CONTEXT_OPTIONS = exports.PLAYDROP_SURFACE_PROFILES = void 0;
|
|
3
|
+
exports.PLAYDROP_SURFACE_CONTEXT_OPTIONS = exports.PLAYDROP_SURFACE_PROFILES = exports.PLAYDROP_MOBILE_USER_AGENT = void 0;
|
|
4
4
|
exports.clonePlaydropSurfaceContextOptions = clonePlaydropSurfaceContextOptions;
|
|
5
5
|
exports.buildPlaywrightMcpSurfaceArgs = buildPlaywrightMcpSurfaceArgs;
|
|
6
|
-
|
|
6
|
+
exports.PLAYDROP_MOBILE_USER_AGENT = 'Mozilla/5.0 (iPhone; CPU iPhone OS 26_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1';
|
|
7
7
|
exports.PLAYDROP_SURFACE_PROFILES = {
|
|
8
8
|
DESKTOP: {
|
|
9
9
|
contextOptions: {
|
|
@@ -21,7 +21,7 @@ exports.PLAYDROP_SURFACE_PROFILES = {
|
|
|
21
21
|
deviceScaleFactor: 3,
|
|
22
22
|
isMobile: true,
|
|
23
23
|
hasTouch: true,
|
|
24
|
-
userAgent:
|
|
24
|
+
userAgent: exports.PLAYDROP_MOBILE_USER_AGENT,
|
|
25
25
|
},
|
|
26
26
|
playwrightMcpDevice: 'iPhone 13 landscape',
|
|
27
27
|
},
|
|
@@ -32,7 +32,7 @@ exports.PLAYDROP_SURFACE_PROFILES = {
|
|
|
32
32
|
deviceScaleFactor: 3,
|
|
33
33
|
isMobile: true,
|
|
34
34
|
hasTouch: true,
|
|
35
|
-
userAgent:
|
|
35
|
+
userAgent: exports.PLAYDROP_MOBILE_USER_AGENT,
|
|
36
36
|
},
|
|
37
37
|
playwrightMcpDevice: 'iPhone 13',
|
|
38
38
|
},
|
|
@@ -60,5 +60,6 @@ function buildPlaywrightMcpSurfaceArgs(surface) {
|
|
|
60
60
|
...(profile.playwrightMcpDevice ? ['--device', profile.playwrightMcpDevice] : []),
|
|
61
61
|
'--viewport-size',
|
|
62
62
|
`${viewport.width}x${viewport.height}`,
|
|
63
|
+
...(profile.contextOptions.userAgent ? ['--user-agent', profile.contextOptions.userAgent] : []),
|
|
63
64
|
];
|
|
64
65
|
}
|
package/dist/apps/validate.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AppTask } from '../catalogue';
|
|
2
2
|
export type AppValidationWarningMode = 'source' | 'bundle';
|
|
3
|
-
export declare function collectAppValidationWarnings(task: AppTask,
|
|
3
|
+
export declare function collectAppValidationWarnings(task: AppTask, _mode?: AppValidationWarningMode): string[];
|
|
4
4
|
export declare function runFormatScript(task: AppTask): Promise<boolean>;
|
|
5
5
|
export declare function validateAppTask(task: AppTask): Promise<void>;
|