Skip to content

Commit f827748

Browse files
Merge pull request #15 from percy/release/v1.1.0-beta.1
release v1.1.0-beta.1
2 parents 8e3f02b + 885bba7 commit f827748

7 files changed

Lines changed: 100 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@ All notable changes to `@percy/maestro-app` are documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [1.1.0-beta.1] — 2026-06-25
8+
9+
Second pre-release of the `1.1.0` self-hosted line. No customer-facing behaviour change over `1.1.0-beta.0` — this is a release-hygiene bump that completes the RELEASING.md "Bump checklist" the `beta.0` cut had left partially applied.
10+
11+
### Changed
12+
13+
- **`percy/scripts/percy-screenshot.js`**`clientInfo` telemetry string bumps from `percy-maestro-app/1.1.0-beta.0` to `percy-maestro-app/1.1.0-beta.1`, keeping the embedded literal in lockstep with `package.json` per the bump checklist.
14+
15+
### Fixed
16+
17+
- **`package-lock.json`** — synced the root and `packages[""]` `version` (stale `1.0.0`) to the current `package.json` version.
18+
- **`test/unit/percy-screenshot.test.mjs`** — the `clientInfo` assertion now reads the expected version from `package.json` instead of hard-coding it, so it tracks future bumps automatically. Updated the missing-`PERCY_SESSION_ID` test to assert the current self-hosted upload behaviour (the upload-gate relaxation shipped in `1.1.0-beta.0`); it had still been asserting the pre-`beta.0` skip-and-log behaviour.
19+
720
## [1.1.0-beta.0] — 2026-06-24
821

922
First pre-release of self-hosted (non-BrowserStack) Maestro support. Promotes the GraalJS-side changes from PR #7 — together with `@percy/cli@1.32.3-beta.0` — to make `percy app:exec -- maestro test <flow>.yaml` work end-to-end on customer-managed devices (local dev machines, Maestro Cloud, customer CI). Backward-compatible: BrowserStack App Automate runs are byte-identical to `1.0.0`.

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@percy/maestro-app",
3-
"version": "1.1.0-beta.0",
3+
"version": "1.1.0-beta.1",
44
"description": "Percy SDK for Maestro mobile testing — visual testing for Android and iOS Maestro flows on BrowserStack",
55
"license": "MIT",
66
"author": "Perceptual Inc.",

percy/scripts/percy-screenshot.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ try {
296296
}
297297

298298
payload.platform = maestro.platform;
299-
payload.clientInfo = "percy-maestro-app/1.1.0-beta.0";
299+
payload.clientInfo = "percy-maestro-app/1.1.0-beta.1";
300300
payload.environmentInfo = "percy-maestro";
301301

302302
// POST to the relay endpoint — Percy CLI reads the file from disk

test/unit/percy-healthcheck.test.mjs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,24 @@ test('PERCY_SERVER env override is honoured', () => {
4545
assert.equal(httpCalls.get[0][0], 'http://localhost:9999' + HC);
4646
});
4747

48+
test('PERCY_SERVER_ADDRESS used when set; PERCY_SERVER takes precedence when both set', () => {
49+
// PERCY_SERVER_ADDRESS is the self-hosted `percy app:exec` export; it wins
50+
// over the default but loses to an explicit PERCY_SERVER.
51+
const addrOnly = runScript('healthcheck', {
52+
platform: 'android',
53+
env: { PERCY_SERVER_ADDRESS: 'http://addr:1' },
54+
http: { get: [OK_RESPONSE({})] },
55+
});
56+
assert.equal(addrOnly.httpCalls.get[0][0], 'http://addr:1' + HC);
57+
58+
const both = runScript('healthcheck', {
59+
platform: 'android',
60+
env: { PERCY_SERVER_ADDRESS: 'http://addr:1', PERCY_SERVER: 'http://explicit:2' },
61+
http: { get: [OK_RESPONSE({})] },
62+
});
63+
assert.equal(both.httpCalls.get[0][0], 'http://explicit:2' + HC);
64+
});
65+
4866
test('4xx response → reachable-but-rejected banner, disabled', () => {
4967
const { output, logs } = runScript('healthcheck', {
5068
platform: 'android',

test/unit/percy-prepare-screenshot.test.mjs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,22 @@ test('inline healthcheck: PERCY_SERVER override and no-version success', () => {
7575
assert.ok(logs.some((l) => l === '[percy] Percy CLI healthcheck passed.'));
7676
});
7777

78+
test('inline healthcheck: PERCY_SERVER_ADDRESS used; PERCY_SERVER wins when both set', () => {
79+
const addrOnly = runScript('prepare', {
80+
platform: 'ios',
81+
env: { SCREENSHOT_NAME: 'x', PERCY_SERVER_ADDRESS: 'http://addr:3' },
82+
http: { get: [OK_RESPONSE({})] },
83+
});
84+
assert.equal(addrOnly.httpCalls.get[0][0], 'http://addr:3/percy/healthcheck');
85+
86+
const both = runScript('prepare', {
87+
platform: 'ios',
88+
env: { SCREENSHOT_NAME: 'x', PERCY_SERVER_ADDRESS: 'http://addr:3', PERCY_SERVER: 'http://explicit:4' },
89+
http: { get: [OK_RESPONSE({})] },
90+
});
91+
assert.equal(both.httpCalls.get[0][0], 'http://explicit:4/percy/healthcheck');
92+
});
93+
7894
test('inline healthcheck: 4xx disables with rejected banner', () => {
7995
const { output, logs } = runScript('prepare', {
8096
platform: 'android',

test/unit/percy-screenshot.test.mjs

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
11
// test/unit/percy-screenshot.test.mjs
22
import { test } from 'node:test';
33
import assert from 'node:assert/strict';
4+
import fs from 'node:fs';
5+
import path from 'node:path';
6+
import { fileURLToPath } from 'node:url';
47
import { runScript, OK_RESPONSE, NOT_OK_RESPONSE, THROW } from './harness.mjs';
58

69
const SS = '/percy/maestro-screenshot';
710

11+
// Read the version from package.json so the clientInfo assertion tracks the
12+
// release bump automatically and never goes stale. The shipped
13+
// percy-screenshot.js embeds the clientInfo string as a literal (GraalJS in
14+
// Maestro can't require package.json at runtime); the RELEASING.md "Bump
15+
// checklist" keeps the literal and package.json in lockstep, and this test is
16+
// the guard that they actually match.
17+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
18+
const PKG = JSON.parse(
19+
fs.readFileSync(path.resolve(__dirname, '..', '..', 'package.json'), 'utf8')
20+
);
21+
const EXPECTED_CLIENT_INFO = 'percy-maestro-app/' + PKG.version;
22+
823
// Helper: an "enabled" output so we skip self-init and go straight to the
924
// upload path. percyServer set so the `output.percyServer || default` reads
1025
// the truthy side.
@@ -65,6 +80,27 @@ test('self-init: PERCY_SERVER override used for healthcheck and upload', () => {
6580
assert.equal(httpCalls.post[0][0], 'http://srv:1' + SS);
6681
});
6782

83+
test('self-init: PERCY_SERVER_ADDRESS used; PERCY_SERVER wins when both set', () => {
84+
const addrOnly = runScript('screenshot', {
85+
platform: 'android',
86+
env: { SCREENSHOT_NAME: 'home', PERCY_SESSION_ID: 's', PERCY_SERVER_ADDRESS: 'http://addr:5' },
87+
http: { get: [OK_RESPONSE({})], post: [OK_RESPONSE()] },
88+
});
89+
assert.equal(addrOnly.httpCalls.get[0][0], 'http://addr:5/percy/healthcheck');
90+
assert.equal(addrOnly.httpCalls.post[0][0], 'http://addr:5' + SS);
91+
92+
const both = runScript('screenshot', {
93+
platform: 'android',
94+
env: {
95+
SCREENSHOT_NAME: 'home', PERCY_SESSION_ID: 's',
96+
PERCY_SERVER_ADDRESS: 'http://addr:5', PERCY_SERVER: 'http://explicit:6',
97+
},
98+
http: { get: [OK_RESPONSE({})], post: [OK_RESPONSE()] },
99+
});
100+
assert.equal(both.httpCalls.get[0][0], 'http://explicit:6/percy/healthcheck');
101+
assert.equal(both.httpCalls.post[0][0], 'http://explicit:6' + SS);
102+
});
103+
68104
test('self-init: unsupported platform disables and skips upload', () => {
69105
const { output, httpCalls, logs } = runScript('screenshot', {
70106
platform: 'tvos',
@@ -181,14 +217,22 @@ test('enabled with invalid SCREENSHOT_NAME → regex throw, caught, logged', ()
181217
assert.ok(logs.some((l) => l.includes('SCREENSHOT_NAME must match')));
182218
});
183219

184-
test('enabled, valid name, MISSING session id → logs and does not upload', () => {
185-
const { httpCalls, logs } = runScript('screenshot', {
220+
test('enabled, valid name, MISSING session id → uploads as selfhosted (no session-id gate)', () => {
221+
// The PERCY_SESSION_ID upload gate was relaxed in 1.1.0-beta.0 (see
222+
// CHANGELOG "Changed" + the runtime-field plan): a missing session id no
223+
// longer skips the upload. The POST now fires with runtime "selfhosted" and
224+
// no sessionId field; the CLI relay's runtime-aware handler picks the
225+
// self-hosted file-find path.
226+
const { httpCalls } = runScript('screenshot', {
186227
platform: 'android',
187228
output: enabled(),
188229
env: { SCREENSHOT_NAME: 'home' },
230+
http: { post: [OK_RESPONSE()] },
189231
});
190-
assert.equal(httpCalls.post.length, 0);
191-
assert.ok(logs.some((l) => l.includes('PERCY_SESSION_ID not set')));
232+
assert.equal(httpCalls.post.length, 1, 'self-hosted upload fires without a session id');
233+
const payload = JSON.parse(httpCalls.post[0][1].body);
234+
assert.equal(payload.runtime, 'selfhosted');
235+
assert.equal(payload.sessionId, undefined, 'no sessionId field when PERCY_SESSION_ID absent');
192236
});
193237

194238
// ---------------------------------------------------------------------------
@@ -208,7 +252,7 @@ test('android default tag/name/dimensions when env vars absent', () => {
208252
assert.equal(payload.statusBarHeight, 120);
209253
assert.equal(payload.navBarHeight, 100);
210254
assert.equal(payload.platform, 'android');
211-
assert.equal(payload.clientInfo, 'percy-maestro-app/1.0.0');
255+
assert.equal(payload.clientInfo, EXPECTED_CLIENT_INFO);
212256
assert.equal(payload.environmentInfo, 'percy-maestro');
213257
});
214258

0 commit comments

Comments
 (0)