Skip to content

Commit 27839a0

Browse files
author
DavidQ
committed
Remove inline styles and automate preview rewrite timeout check in Preview Generator V2 - PR_26126_022-preview-generator-v2-no-inline-style-and-auto-rewrite
1 parent 6225344 commit 27839a0

5 files changed

Lines changed: 199 additions & 287 deletions

File tree

docs/dev/codex_commands.md

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# Codex Commands - PR_26126_021-preview-generator-v2-last-generated-placement
1+
# Codex Commands - PR_26126_022-preview-generator-v2-no-inline-style-and-auto-rewrite
22

33
```bash
4-
codex run "Create PR_26126_021-preview-generator-v2-last-generated-placement. Fix Preview Generator V2 UI only. Preserve existing generation behavior. Under the \"Paths or IDs\" control in the left panel, add a \"Last Generated Image\" section that displays the most recently generated preview. This must update on every Generate Preview action, replace the previous image (no history), and show an empty state before first generate. Keep it within the left panel accordion flow, directly below the Paths or IDs control. Do not move existing controls. Do not modify samples. Do not add schema. Produce review artifacts."
4+
codex run "Create PR_26126_022-preview-generator-v2-no-inline-style-and-auto-rewrite. Fix Preview Generator V2 UI/behavior only. Preserve existing generation behavior. Remove all inline style attributes from HTML; move styling into the existing Preview Generator V2 stylesheet/classes using Palette Manager V2 style conventions. Do not show the text \"Only rewrite if preview.svg contains literal \\\"Capture timeout\\\"\" in the UI. Instead, if an existing preview.svg exists, automatically test its contents; only rewrite/regenerate when preview.svg contains the literal text \"Capture timeout\". If preview.svg exists and does not contain that text, skip rewrite and log the decision in the status textarea. Do not modify samples. Do not add schema. Produce review artifacts."
55
```
66

77
## Validation Commands
@@ -36,72 +36,73 @@ await page.addInitScript(() => {
3636
class FakeFileHandle {
3737
constructor(path, existing = null) { this.kind = 'file'; this.name = path.split('/').pop(); this.path = path; this._existing = existing; }
3838
async getFile() { return new FakeFile(this._existing || ''); }
39-
async createWritable() { const path = this.path; return { async write(content) { writes.push({ path, content: String(content) }); }, async close() {} }; }
39+
async createWritable() { const handle = this; const path = this.path; return { async write(content) { writes.push({ path, content: String(content) }); handle._existing = String(content); }, async close() {} }; }
4040
}
4141
class FakeDirectoryHandle {
4242
constructor(name = 'HTML-JavaScript-Gaming', path = '') { this.kind = 'directory'; this.name = name; this.path = path; this.children = new Map(); }
4343
async getDirectoryHandle(name) { const key = `dir:${name}`; if (!this.children.has(key)) { const nextPath = this.path ? `${this.path}/${name}` : name; this.children.set(key, new FakeDirectoryHandle(name, nextPath)); } return this.children.get(key); }
4444
async getFileHandle(name, options = {}) { const key = `file:${name}`; if (!this.children.has(key)) { if (!options.create) throw new DOMException('Not found', 'NotFoundError'); const nextPath = this.path ? `${this.path}/${name}` : name; this.children.set(key, new FakeFileHandle(nextPath)); } return this.children.get(key); }
4545
}
46+
async function addFile(root, path, text) {
47+
const parts = path.split('/').filter(Boolean);
48+
let current = root;
49+
for (const part of parts.slice(0, -1)) current = await current.getDirectoryHandle(part);
50+
const fileHandle = await current.getFileHandle(parts.at(-1), { create: true });
51+
fileHandle._existing = text;
52+
}
4653
window.__previewGeneratorV2Writes = writes;
47-
window.showDirectoryPicker = async () => new FakeDirectoryHandle();
54+
window.__previewGeneratorV2Root = new FakeDirectoryHandle();
55+
window.__previewGeneratorV2Ready = (async () => {
56+
await addFile(window.__previewGeneratorV2Root, 'samples/phase-01/0107/assets/images/preview.svg', '<svg><text>Healthy preview</text></svg>');
57+
await addFile(window.__previewGeneratorV2Root, 'samples/phase-01/0102/assets/images/preview.svg', '<svg><text>Capture timeout</text></svg>');
58+
})();
59+
window.showDirectoryPicker = async () => {
60+
await window.__previewGeneratorV2Ready;
61+
return window.__previewGeneratorV2Root;
62+
};
4863
});
4964
5065
await page.goto(`${server.baseUrl}/tools/preview-generator-v2/index.html`, { waitUntil: 'domcontentloaded' });
5166
await page.waitForSelector('#shared-theme-header');
5267
await page.waitForFunction(() => Array.from(document.querySelectorAll('.preview-generator-v2 .accordion-v2__header')).every((header) => header.dataset.accordionV2Bound === 'true'));
53-
54-
const textareaBox = await page.locator('#sampleList').boundingBox();
55-
const lastGeneratedBox = await page.locator('#lastGeneratedImageSection').boundingBox();
56-
if (!textareaBox || !lastGeneratedBox || lastGeneratedBox.y <= textareaBox.y) throw new Error('Last Generated Image should render below Paths or IDs input.');
57-
if (!(await page.locator('#lastGeneratedImageEmpty').isVisible())) throw new Error('Last Generated Image empty state should be visible before first generate.');
58-
if (await page.locator('#lastGeneratedImagePreview').isVisible()) throw new Error('Last Generated Image preview should be hidden before first generate.');
68+
const bodyText = await page.locator('body').innerText();
69+
if (bodyText.includes('Only rewrite if preview.svg contains literal')) throw new Error('Manual capture-timeout rewrite text should not be visible.');
70+
const previewInlineStyleCount = await page.locator('.preview-generator-v2 [style]').count();
71+
if (previewInlineStyleCount !== 0) throw new Error(`Expected no inline style attributes inside Preview Generator V2 UI, got ${previewInlineStyleCount}`);
5972
6073
await page.fill('#baseUrl', server.baseUrl);
6174
await page.fill('#waitMs', '3000');
6275
await page.fill('#sampleList', '0107');
63-
await page.check('#forceRewrite');
6476
await page.check('#targetTypeSamples');
6577
await page.click('#pickRepoBtn');
6678
await page.waitForFunction(() => !document.getElementById('executeBtn').disabled);
6779
await page.click('#executeBtn');
68-
await page.waitForFunction(() => document.getElementById('lastGeneratedImagePreview') && !document.getElementById('lastGeneratedImagePreview').hidden, null, { timeout: 35000 });
69-
if (await page.locator('#lastGeneratedImageEmpty').isVisible()) throw new Error('Last Generated Image empty state should hide after generate.');
70-
const firstSrc = await page.locator('#lastGeneratedImage').getAttribute('src');
71-
const firstMeta = await page.locator('#lastGeneratedImageMeta').innerText();
72-
if (!firstSrc?.startsWith('blob:')) throw new Error(`Last Generated Image should use an object URL, got ${firstSrc}`);
73-
if (!firstMeta.includes('0107')) throw new Error(`Last Generated Image meta should include first generated label, got ${firstMeta}`);
74-
await page.waitForFunction(() => (window.__previewGeneratorV2Writes || []).length === 1);
80+
await page.waitForFunction(() => document.getElementById('log').textContent.includes('existing-preview-without-capture-timeout'), null, { timeout: 35000 });
81+
let writes = await page.evaluate(() => window.__previewGeneratorV2Writes || []);
82+
if (writes.length !== 0) throw new Error(`Existing healthy preview should skip rewrite, got ${writes.length} writes.`);
7583
84+
await page.click('#clearLogBtn');
7685
await page.fill('#sampleList', '0102');
7786
await page.waitForFunction(() => !document.getElementById('executeBtn').disabled);
7887
await page.click('#executeBtn');
79-
await page.waitForFunction((previousSrc) => {
80-
const img = document.getElementById('lastGeneratedImage');
81-
return img && img.getAttribute('src') && img.getAttribute('src') !== previousSrc;
82-
}, firstSrc, { timeout: 35000 });
83-
const secondSrc = await page.locator('#lastGeneratedImage').getAttribute('src');
84-
const secondMeta = await page.locator('#lastGeneratedImageMeta').innerText();
85-
if (!secondSrc?.startsWith('blob:')) throw new Error(`Replacement Last Generated Image should use an object URL, got ${secondSrc}`);
86-
if (secondSrc === firstSrc) throw new Error('Last Generated Image should replace the prior object URL.');
87-
if (!secondMeta.includes('0102')) throw new Error(`Last Generated Image meta should include second generated label, got ${secondMeta}`);
88-
await page.waitForFunction(() => (window.__previewGeneratorV2Writes || []).length === 2);
89-
const writes = await page.evaluate(() => window.__previewGeneratorV2Writes || []);
90-
if (!writes[0].path.endsWith('samples/phase-01/0107/assets/images/preview.svg')) throw new Error(`Unexpected first write path: ${writes[0].path}`);
91-
if (!writes[1].path.endsWith('samples/phase-01/0102/assets/images/preview.svg')) throw new Error(`Unexpected second write path: ${writes[1].path}`);
88+
await page.waitForFunction(() => document.getElementById('log').textContent.includes('contains Capture timeout; rewriting'), null, { timeout: 35000 });
89+
await page.waitForFunction(() => document.getElementById('lastGeneratedImagePreview') && !document.getElementById('lastGeneratedImagePreview').hidden, null, { timeout: 35000 });
90+
writes = await page.evaluate(() => window.__previewGeneratorV2Writes || []);
91+
if (writes.length !== 1) throw new Error(`Existing Capture timeout preview should rewrite once, got ${writes.length} writes.`);
92+
if (!writes[0].path.endsWith('samples/phase-01/0102/assets/images/preview.svg')) throw new Error(`Unexpected rewrite path: ${writes[0].path}`);
9293
if (errors.length || consoleErrors.length) throw new Error([...errors, ...consoleErrors].join(' | '));
9394
await browser.close();
9495
await server.close();
95-
console.log('preview-generator-v2 last generated image placement smoke valid');
96+
console.log('preview-generator-v2 automatic capture-timeout rewrite gate smoke valid');
9697
'@ | node --input-type=module -
9798
```
9899

99100
## Notes
100101

101-
The targeted Playwright smoke validates the empty state, placement below `Paths or IDs`, first generated preview render, and second Generate Preview replacement without history.
102+
The targeted Playwright smoke validates the visible manual capture-timeout checkbox text is absent, Preview Generator V2-owned UI has no inline style attributes, existing healthy previews skip rewrite with a status log, and existing timeout previews rewrite and update Last Generated Image.
102103

103104
`npm run test:workspace-v2` was attempted, but the script is not defined in this checkout.
104105

105-
Full samples smoke test was skipped because this PR is scoped to Preview Generator V2 UI only.
106+
Full samples smoke test was skipped because this PR is scoped to Preview Generator V2 UI/behavior only.
106107

107-
An unrelated unstaged sample preview SVG change was present before this PR and was left untouched.
108+
Unstaged sample preview SVG changes were present before this PR and were left untouched.

docs/dev/commit_comment.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Add Preview Generator V2 last generated image preview - PR_26126_021-preview-generator-v2-last-generated-placement
1+
Automate Preview Generator V2 capture-timeout rewrite gate - PR_26126_022-preview-generator-v2-no-inline-style-and-auto-rewrite

docs/dev/reports/codex_changed_files.txt

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,10 @@ M docs/dev/codex_commands.md
33
M docs/dev/commit_comment.txt
44
M docs/dev/reports/codex_changed_files.txt
55
M docs/dev/reports/codex_review.diff
6-
M samples/phase-02/0224/assets/images/preview.svg
7-
M samples/phase-02/0225/assets/images/preview.svg
8-
M samples/phase-02/0226/assets/images/preview.svg
9-
M samples/phase-02/0227/assets/images/preview.svg
106
M tools/preview-generator-v2/index.html
117

128
# git diff --cached --stat
13-
docs/dev/codex_commands.md | 79 ++++++++++++++--------------
14-
docs/dev/commit_comment.txt | 2 +-
15-
tools/preview-generator-v2/index.html | 91 ++++++++++++++++++++++++++++++++
16-
3 files changed, 119 insertions(+), 53 deletions(-)
17-
18-
# unstaged sample changes
19-
Unstaged sample preview SVG changes were present in the worktree and were not staged or packaged for this PR.
9+
docs/dev/codex_commands.md | 71 ++++++++++++++++++-----------------
10+
docs/dev/commit_comment.txt | 2 +-
11+
tools/preview-generator-v2/index.html | 21 +++++------
12+
3 files changed, 46 insertions(+), 48 deletions(-)

0 commit comments

Comments
 (0)