mirror of
https://github.com/vxcontrol/pentagi.git
synced 2026-08-24 20:16:30 +00:00
chore(e2e): trim narration and self-justifying comments; drop a stale one
An audit of the comments added since the feature base flagged a batch of
justification openers ("Not a copy-paste", "Live entry not dead weight"),
"there's a test for it" cross-refs, and how-we-found-it war-stories. Cut the
narration and keep the load-bearing fact in each. One was actively wrong:
playwright.config.ts still described the `maxDiffPixelRatio` anti-aliasing
budget that 5cec81b replaced with an absolute `maxDiffPixels` — removed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
9649e7f313
commit
a7c0c19b53
@@ -14,7 +14,6 @@ on:
|
||||
- "v[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
|
||||
# A PR's synchronize pushes supersede each other; keep only the latest run per ref.
|
||||
concurrency:
|
||||
group: ci-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
@@ -7,15 +7,11 @@ const owns = (dir: string, file: string): boolean => file === dir || file.starts
|
||||
|
||||
/**
|
||||
* Maps a set of changed repo files to the manifest routes they touch, by
|
||||
* prefix-matching each change against a route's owning source dirs. This is the
|
||||
* substrate for selective runs and for scoping the exploratory agent to the
|
||||
* changed surface. Pure — the CLI and the vitest unit test both drive it.
|
||||
* prefix-matching each change against a route's owning source dirs.
|
||||
*
|
||||
* - no frontend change → no routes (a backend-only diff; the caller falls back
|
||||
* to the full suite, and schema-compat covers the backend contract);
|
||||
* - a frontend change owned by no route → all routes (shared infra: the e2e
|
||||
* engine, config, src/lib, a provider used everywhere) — conservative on
|
||||
* purpose, since over-running is safe and under-running hides a regression;
|
||||
* - no frontend change → no routes (the caller falls back to the full suite);
|
||||
* - a frontend change owned by no route → all routes (shared infra: e2e engine,
|
||||
* config, src/lib, an everywhere-provider) — over-run rather than under-run;
|
||||
* - otherwise → the routes whose `sources` the changes fall under.
|
||||
*
|
||||
* Paths are repo-relative (`frontend/...`); `sources` are `frontend/`-relative.
|
||||
|
||||
@@ -12,9 +12,8 @@ const errorsTest = base.extend<{ pageErrorLog: PageErrorLog }>({
|
||||
|
||||
await use(log);
|
||||
|
||||
// Asserted here rather than left to the spec: a spec that never destructured this
|
||||
// fixture collected nothing, so opting in was the same as opting out. Console errors
|
||||
// stay with `expectCleanPage` — several specs drive genuine 4xx paths that log one.
|
||||
// Auto (not opt-in): a spec that never destructured this fixture would assert nothing.
|
||||
// Console errors stay with `expectCleanPage` — several specs drive 4xx paths that log one.
|
||||
baseExpect(log.pageErrors, 'no uncaught page errors').toEqual([]);
|
||||
},
|
||||
{ auto: true },
|
||||
|
||||
@@ -35,8 +35,6 @@ export const RULES = [
|
||||
match: /get_number/,
|
||||
toolCalls: [{ args: { value: 1 }, name: 'get_number' }],
|
||||
},
|
||||
// The task reporter summarizes the finished task and only accepts the
|
||||
// report_result tool.
|
||||
{
|
||||
label: 'task-report',
|
||||
match: /report_result|TASK EXECUTION EVALUATOR AND REPORTER/,
|
||||
@@ -51,8 +49,7 @@ export const RULES = [
|
||||
},
|
||||
],
|
||||
},
|
||||
// The refiner re-plans between subtasks and only accepts subtask_patch;
|
||||
// an empty operations list means "plan unchanged".
|
||||
// An empty operations list means "plan unchanged".
|
||||
{
|
||||
label: 'subtask-refine',
|
||||
match: /subtask_patch/,
|
||||
|
||||
@@ -18,9 +18,8 @@ const flows: ResultOf<typeof FlowsDocument> = { flows: [] };
|
||||
|
||||
const flowTemplates: ResultOf<typeof FlowTemplatesDocument> = { flowTemplates: [] };
|
||||
|
||||
// Live entry, not dead weight: after a websocket reconnect the app re-requests
|
||||
// resources on the wire with {recursive:true} (removing this red-lights the
|
||||
// reconnect spec on the 501 gate).
|
||||
// After a websocket reconnect the app re-requests resources on the wire with {recursive:true};
|
||||
// removing this entry red-lights the reconnect spec on the 501 gate.
|
||||
const resources: ResultOf<typeof ResourcesDocument> = { resources: [] };
|
||||
|
||||
const providers: ResultOf<typeof ProvidersDocument> = { providers: [] };
|
||||
|
||||
@@ -181,8 +181,8 @@ export const flowsCassette = (override: Cassette = {}): Cassette =>
|
||||
{
|
||||
frames: [
|
||||
...FLOW_A_STREAMED_IDS.map((id) => addedFrame(makeMessage(id, '5'), 80)),
|
||||
// Not a copy-paste: a resubscribe replays what the refetch already
|
||||
// delivered, and the sentinel after it proves the replay was received.
|
||||
// A resubscribe replays what the refetch already delivered; the sentinel
|
||||
// after it proves the replay was received.
|
||||
{
|
||||
...addedFrame(makeMessage(FLOW_A_RECONNECT_ID, '5'), 0),
|
||||
whenFlag: REPLAY_FLAG,
|
||||
|
||||
@@ -54,7 +54,7 @@ export const handleWsConnection = (
|
||||
|
||||
case 'connection_init': {
|
||||
// Ack immediately; a frame sent before the ack is a graphql-ws protocol
|
||||
// violation that closes the socket. Ack-first ordering is pinned by the unit test.
|
||||
// violation that closes the socket.
|
||||
send({ type: 'connection_ack' });
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -45,14 +45,10 @@ if ((tier === 'stand' || tier === 'local') && !TIERS[tier].baseURL) {
|
||||
}
|
||||
|
||||
export default defineConfig<BackendOptions>({
|
||||
// A colour change must move enough pixels to fail. The baselines and the run both
|
||||
// render in the pinned container (the host path is blocked above), so there is no
|
||||
// host-vs-CI rasterisation noise to absorb — tighten the per-pixel threshold below
|
||||
// Playwright's default 0.2 so a one-step palette shift is caught, with a small
|
||||
// maxDiffPixelRatio for anti-aliasing at glyph edges. cross/contrast.spec.ts still
|
||||
// measures colour numerically as the belt-and-suspenders check.
|
||||
// Absolute, not a ratio: 1% of a 1280x720 baseline is 9,216 pixels, more than any one foreground
|
||||
// token covers, so a token could change hue with every baseline still matching.
|
||||
// token covers, so a token could change hue with every baseline still matching. Baselines and
|
||||
// run both render in the pinned container (the host path is blocked above), so 200px absorbs the
|
||||
// glyph anti-aliasing without host-vs-CI noise.
|
||||
expect: {
|
||||
toHaveScreenshot: { maxDiffPixels: 200, threshold: 0.02 },
|
||||
},
|
||||
|
||||
@@ -56,8 +56,7 @@ const SANCTIONED_VARIANTS = [
|
||||
* its path; a tab panel by `${path} [${tab}]`. Exact strings: they waive one node, not a rule.
|
||||
*/
|
||||
const ACCEPTED: Record<string, string[]> = {
|
||||
// file-manager.tsx expand-all control; changing it moves pixels, so it goes with the design pass.
|
||||
// Same control renders in the flow Files tab, so it is waived there under the same rationale.
|
||||
// file-manager.tsx expand-all control, on /resources and embedded in the flow Files tab.
|
||||
'/resources': ['button: hover:text-blue-400'],
|
||||
[`${routes.flow('5')} [Files]`]: ['button: hover:text-blue-400'],
|
||||
};
|
||||
|
||||
@@ -72,7 +72,6 @@ test.describe('resources', { tag: '@coverage' }, () => {
|
||||
await page.goto('/resources');
|
||||
|
||||
await expect(page.getByText('No resources yet')).toBeVisible();
|
||||
// The CTA, not just the title — the empty state's whole point is the upload affordance.
|
||||
// Scope to the drop zone (its hint is unique) so the toolbar's Upload button is excluded.
|
||||
const dropZone = page.locator('div').filter({ hasText: 'Up to 300 MB per file' }).last();
|
||||
|
||||
|
||||
@@ -69,9 +69,9 @@ test.describe('flow subscriptions', { tag: ['@flows', '@smoke'] }, () => {
|
||||
});
|
||||
|
||||
/**
|
||||
* Not a duplicate of the round trip above: leaving via `/flows` unmounts FlowProvider (app.tsx
|
||||
* wraps only `flows/:flowId`), so stream A is already closed there. Only the pager keeps the
|
||||
* provider mounted and merely swaps the subscription variables.
|
||||
* Leaving via `/flows` unmounts FlowProvider (app.tsx wraps only `flows/:flowId`), so stream A is
|
||||
* already closed there. Only the pager keeps the provider mounted and merely swaps the subscription
|
||||
* variables — the one path where a superseded stream can still write into the flow on screen.
|
||||
*/
|
||||
test.describe('flow subscriptions across a pager switch', { tag: '@flows' }, () => {
|
||||
test.use({ cassette: pagerStreamsCassette() });
|
||||
|
||||
@@ -4,8 +4,8 @@ import { readTerminalBuffer } from '../../helpers/terminal.ts';
|
||||
|
||||
test.describe('real backend flow run', { tag: '@real' }, () => {
|
||||
test('runs a flow end-to-end through the mock LLM', async ({ page }) => {
|
||||
// Above the sum of the step timeouts below (60+30+90+90+90+60 = 420s); at 240s a legitimately
|
||||
// slow-but-passing real run was killed mid-step with a generic timeout, masking the real state.
|
||||
// Above the sum of the step timeouts below (60+30+90+90+90+60 = 420s), so a slow-but-passing
|
||||
// run is not killed mid-step with a generic timeout that masks the real state.
|
||||
test.setTimeout(450_000);
|
||||
|
||||
const pageErrors: string[] = [];
|
||||
|
||||
@@ -23,9 +23,8 @@ compose() {
|
||||
# sandboxes for any flow id starting with 9.
|
||||
remove_e2e_sandboxes() {
|
||||
docker ps -aq --filter 'name=^/?pentagi-terminal-9[0-9]{4,}$' | xargs -r docker rm -f
|
||||
# Each sandbox also gets a `<container>-data` volume, created on the socket
|
||||
# outside the compose project — removing the container leaves it behind, so
|
||||
# every Tier-2 run used to add one more dangling volume.
|
||||
# Each sandbox also gets a `<container>-data` volume, created on the socket outside the compose
|
||||
# project — removing the container leaves it behind, so it needs its own cleanup.
|
||||
docker volume ls -q --filter 'name=^pentagi-terminal-9[0-9]{4,}-data$' | xargs -r docker volume rm
|
||||
}
|
||||
|
||||
|
||||
@@ -159,8 +159,6 @@ describe('SettingsProvider create-form type guards', () => {
|
||||
expect(navigate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// The seeding effect re-runs on every settingsProviders refetch (a fresh `data` reference under
|
||||
// cache-and-network); keepDirtyValues is what stops that reset from wiping an in-flight edit.
|
||||
it('preserves an in-flight edit across a background refetch', () => {
|
||||
state.providerId = 'edit-1';
|
||||
const { rerender } = render(<SettingsProvider />);
|
||||
@@ -171,7 +169,6 @@ describe('SettingsProvider create-form type guards', () => {
|
||||
|
||||
fireEvent.change(nameInput, { target: { value: 'My Unsaved Edit' } });
|
||||
|
||||
// A refetch delivers a new `data` object with the same server content, re-firing the effect.
|
||||
queryResult.data = { settingsProviders };
|
||||
rerender(<SettingsProvider />);
|
||||
|
||||
|
||||
@@ -1205,7 +1205,7 @@ function SettingsProvider() {
|
||||
},
|
||||
// The seeding effect re-runs on every settingsProviders refetch (cache-and-network +
|
||||
// replaceWithIncoming gives a fresh `data`); without this a background refetch landing
|
||||
// mid-edit silently wipes the unsaved form. Matches settings-prompt and template.
|
||||
// mid-edit silently wipes the unsaved form.
|
||||
resetOptions: { keepDirtyValues: true },
|
||||
schema: formSchema,
|
||||
});
|
||||
|
||||
@@ -39,8 +39,8 @@ import { Log } from '@/lib/log';
|
||||
|
||||
/**
|
||||
* Under `errorPolicy:'all'` a partial not-found error surfaces alongside a flow that loaded fine, so
|
||||
* the not-found disjunct gates on `!flowData?.flow` — mirroring `flowLoadError` and the toast below.
|
||||
* Without the gate that partial error redirects the user off a flow that rendered correctly.
|
||||
* the not-found disjunct gates on `!flowData?.flow`. Without the gate that partial error redirects
|
||||
* the user off a flow that rendered correctly.
|
||||
*/
|
||||
export const deriveFlowMissing = (
|
||||
flowData: null | undefined | { flow: unknown },
|
||||
|
||||
Reference in New Issue
Block a user