Merge remote-tracking branch 'origin/main' into docs/structure-department-pages
Build and publish Eldorado documentation / build (pull_request) Successful in 49s
Build and publish Eldorado documentation / build (pull_request) Successful in 49s
This commit is contained in:
commit
9bacb7043a
53 files changed
+974
-390
No files matched your search
@@ -12,10 +12,19 @@ const fs = require('node:fs');
|
||||
const context = await browser.newContext({viewport: {width, height: 1000}, colorScheme: 'light'});
|
||||
const page = await context.newPage();
|
||||
await page.goto(`${base}/eldorado-v1/documentation/strategy/`, {waitUntil: 'networkidle'});
|
||||
const panel = page.locator('.archify-panel--story');
|
||||
await page.addStyleTag({content:'html {scroll-behavior:auto !important;}'});
|
||||
await page.getByText('Conditional long-term Target operating model — not the six-month promise',{exact:true}).focus();
|
||||
await page.keyboard.press('Enter');
|
||||
const panel = page.locator('.archify-panel--story[data-diagram="strategy-target"]');
|
||||
const iframe = panel.locator(width > 700 ? '.story-desktop' : '.story-mobile');
|
||||
await iframe.scrollIntoViewIfNeeded();
|
||||
const frame = await (await iframe.elementHandle()).contentFrame();
|
||||
const showControls = () => iframe.evaluate(n => {
|
||||
scrollTo({top:n.getBoundingClientRect().top+scrollY-120,behavior:'instant'});
|
||||
return new Promise(resolve=>requestAnimationFrame(()=>requestAnimationFrame(resolve)));
|
||||
});
|
||||
await showControls();
|
||||
const activate = async selector => {await frame.locator(selector).focus(); await page.keyboard.press('Enter');};
|
||||
const theme = async value => {
|
||||
await page.waitForFunction(t => document.documentElement.dataset.theme === t, value);
|
||||
await frame.waitForFunction(t => document.documentElement.dataset.theme === t, value);
|
||||
@@ -41,9 +50,9 @@ const fs = require('node:fs');
|
||||
assert(menu.y + menu.height <= viewport.y + viewport.height + 1, `${selector} clips vertically`);
|
||||
};
|
||||
const light = await frame.locator('body').evaluate(n => getComputedStyle(n).backgroundColor);
|
||||
await frame.locator('#btn-theme').click(); await theme('dark');
|
||||
await activate('#btn-theme'); await theme('dark');
|
||||
assert.notEqual(await frame.locator('body').evaluate(n => getComputedStyle(n).backgroundColor), light);
|
||||
await frame.locator('#btn-theme').click(); await theme('light');
|
||||
await activate('#btn-theme'); await theme('light');
|
||||
// Mobile portal theme control lives in the navigation drawer.
|
||||
const portalTheme = async target => {
|
||||
if (width <= 700) await page.getByRole('button', {name: 'Toggle navigation bar'}).click();
|
||||
@@ -52,33 +61,34 @@ const fs = require('node:fs');
|
||||
if (await page.locator('html').getAttribute('data-theme') === target) break;
|
||||
}
|
||||
if (width <= 700) await page.getByRole('button', {name: 'Close navigation bar'}).click();
|
||||
await showControls();
|
||||
};
|
||||
await portalTheme('dark'); await theme('dark');
|
||||
await portalTheme('light'); await theme('light');
|
||||
for (const preset of ['signal-flow', 'blueprint', 'editorial', 'classic']) {
|
||||
await frame.locator('#btn-preset').click();
|
||||
await activate('#btn-preset');
|
||||
await checkMenu('.preset-menu');
|
||||
await frame.locator(`[data-preset-value="${preset}"]`).click();
|
||||
await activate(`[data-preset-value="${preset}"]`);
|
||||
assert.equal(await frame.locator('html').getAttribute('data-preset'), preset);
|
||||
}
|
||||
// A theme change must not reload the iframe or lose the selected visual preset.
|
||||
await frame.locator('#btn-preset').click();
|
||||
await frame.locator('[data-preset-value="blueprint"]').click();
|
||||
await activate('#btn-preset');
|
||||
await activate('[data-preset-value="blueprint"]');
|
||||
await portalTheme('dark'); await theme('dark');
|
||||
assert.equal(await frame.locator('html').getAttribute('data-preset'), 'blueprint');
|
||||
const exports = [];
|
||||
for (const format of ['png', 'jpeg', 'webp', 'svg', 'svg-light', 'svg-dark', 'webm']) {
|
||||
await frame.locator('#btn-export').click();
|
||||
await activate('#btn-export');
|
||||
await checkMenu('.export-menu');
|
||||
if (format === 'webm' && await frame.locator('[data-format="webm"]').isDisabled()) {
|
||||
exports.push({format, unsupported: true});
|
||||
await frame.locator('#btn-export').click();
|
||||
await activate('#btn-export');
|
||||
continue;
|
||||
}
|
||||
console.log(`Export ${width} ${format}`);
|
||||
const [download] = await Promise.all([
|
||||
page.waitForEvent('download', {timeout: 60000}),
|
||||
frame.locator(`[data-format="${format}"]`).click(),
|
||||
activate(`[data-format="${format}"]`),
|
||||
]);
|
||||
assert.equal(await download.failure(), null);
|
||||
const path = `${output}/${width}-${format}-${download.suggestedFilename()}`;
|
||||
@@ -123,14 +133,16 @@ const fs = require('node:fs');
|
||||
await page.evaluate(() => scrollTo({top: 0, behavior: 'instant'}));
|
||||
await page.evaluate(() => new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve))));
|
||||
await page.screenshot({path:`${output}/${width}.png`, fullPage:true});
|
||||
await frame.locator('#btn-theme').click(); await theme('dark');
|
||||
await frame.locator('#btn-theme').focus(); await page.keyboard.press('Enter'); await theme('dark');
|
||||
// Exercise keyboard navigation without racing the portal's smooth scroll.
|
||||
await page.locator('.strategy-content a[href$="/strategy/roadmap/"]').filter({visible:true}).first().focus();
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForURL('**/strategy/roadmap/');
|
||||
await page.goBack({waitUntil:'domcontentloaded'});
|
||||
await page.waitForURL('**/strategy/target-operating-model/');
|
||||
await page.getByRole('heading', {name:'Target operating model', exact:true, level:1}).waitFor();
|
||||
await page.getByRole('heading', {name:'First six months as AI Architect', exact:true, level:1}).waitFor();
|
||||
await page.getByText('Conditional long-term Target operating model — not the six-month promise',{exact:true}).focus();
|
||||
await page.keyboard.press('Enter');
|
||||
const next = page.locator(`.archify-panel--story[data-diagram="strategy-target"] > .story-${width > 700 ? 'desktop' : 'mobile'}`);
|
||||
await next.scrollIntoViewIfNeeded();
|
||||
await (await (await next.elementHandle()).contentFrame()).waitForFunction(() => document.documentElement.dataset.theme === 'dark');
|
||||
|
||||
@@ -26,7 +26,7 @@ const views = {
|
||||
const ids=views[name];
|
||||
geometry.cards.sort((a,b)=>ids.indexOf(a.id)-ids.indexOf(b.id));
|
||||
assert.deepEqual(geometry.cards.map(n => n.id), ids);
|
||||
assert.deepEqual(geometry.cards.map(n => n.number), ids.length === 6 ? ids.map((_,i)=>`Step ${i+1}`) : name === 'strategy-roadmap' ? ['Stage 1','Stage 2'] : ['First','Then']);
|
||||
assert.deepEqual(geometry.cards.map(n => n.number), ids.length === 6 ? ids.map((_,i)=>`Step ${i+1}`) : name === 'strategy-roadmap' ? ['Proposed M1–4','Proposed M5–6'] : ['First','If justified']);
|
||||
assert.equal(geometry.edges.length,ids.length===6?6:1);
|
||||
if(ids.length===6) assert(geometry.edges.some(e=>e.id==='repeat'));
|
||||
for(const edge of geometry.edges) assert(edge.box.left>=0 && edge.box.right<=geometry.width+1 && edge.box.top>=0 && edge.box.bottom<=geometry.height+1, `clipped edge ${name} ${edge.id}`);
|
||||
@@ -60,7 +60,9 @@ const views = {
|
||||
for(const theme of ['light','dark']) {
|
||||
const frameTop=await iframe.evaluate(n=>n.getBoundingClientRect().top+scrollY);
|
||||
await page.evaluate(y=>scrollTo({top:y-120,behavior:'instant'}),frameTop);
|
||||
if(await frame.locator('html').getAttribute('data-theme')!==theme) await frame.locator('#btn-theme').click();
|
||||
if(await frame.locator('html').getAttribute('data-theme')!==theme) {
|
||||
await frame.locator('#btn-theme').focus(); await page.keyboard.press('Enter');
|
||||
}
|
||||
await page.waitForFunction(t=>document.documentElement.dataset.theme===t,theme);
|
||||
const inline=await inspect(frame,name,width<1100);
|
||||
await frame.locator('#btn-preset').focus();await page.keyboard.press('Enter');
|
||||
|
||||
@@ -61,14 +61,14 @@ const fs = require('node:fs');
|
||||
assert.equal(response.status(), 200);
|
||||
assert.equal(await page.locator('h1').innerText(), 'Roadmap');
|
||||
const headings = page.locator('.strategy-content > h2');
|
||||
assert.deepEqual((await headings.allTextContents()).map(s => s.replace(/\u200b/g, '')), ['Two stages toward Target','Stage 1: Delivery first','Improve within each phase','Delivery in practice']);
|
||||
assert.deepEqual((await headings.allTextContents()).map(s => s.replace(/\u200b/g, '')), ['Six months, two investment decisions','Delivery first, replication only if earned','Keep one learning loop','Solo capacity and influence']);
|
||||
const text = await page.locator('.strategy-content').innerText();
|
||||
for (const marker of ['Humans direct, guide and review throughout', 'Delivery keeps improving', 'system-logic source', 'baseline', 'Target operating model']) assert(text.includes(marker), marker);
|
||||
assert(!text.includes('Supporting gate evidence and hold conditions\n\nThese are'));
|
||||
if (width < 700) await page.getByRole('button', {name:'Toggle navigation bar'}).click();
|
||||
const menu = page.locator('.theme-doc-sidebar-menu .menu__link').filter({visible:true});
|
||||
await menu.first().waitFor({state:'visible'});
|
||||
assert.deepEqual((await menu.allTextContents()).slice(0,2), ['Target','Roadmap']);
|
||||
assert.deepEqual((await menu.allTextContents()).slice(0,2), ['Six-month strategy','Roadmap']);
|
||||
if (width < 700) await page.getByRole('button', {name:'Close navigation bar'}).click();
|
||||
const panel = page.locator('.archify-panel--story').first();
|
||||
const iframe = panel.locator(width > 700 ? '.story-desktop' : '.story-mobile');
|
||||
@@ -125,7 +125,7 @@ const fs = require('node:fs');
|
||||
const [download] = await Promise.all([page.waitForEvent('download'), frame.locator('[data-format="svg"]').click()]);
|
||||
assert.equal(await download.failure(), null);
|
||||
await download.saveAs(`${output}/${width}.svg`);
|
||||
assert(fs.readFileSync(`${output}/${width}.svg`, 'utf8').includes('Adopt skills'));
|
||||
assert(fs.readFileSync(`${output}/${width}.svg`, 'utf8').includes('Learn and test'));
|
||||
assert(fs.readFileSync(`${output}/${width}.svg`, 'utf8').includes('eldorado-roadmap-typography'));
|
||||
for (const id of ['skills','autonomy']) {
|
||||
await frame.locator(`svg[role="img"] [data-node-id="${id}"]`).screenshot({path:`${output}/${width}-${id}-card.png`});
|
||||
|
||||
@@ -23,17 +23,19 @@ const fs = require('node:fs');
|
||||
if (width < 700) await page.getByRole('button', {name:'Toggle navigation bar'}).click();
|
||||
const menu = page.locator('.theme-doc-sidebar-menu .menu__link').filter({visible:true});
|
||||
await menu.first().waitFor({state:'visible'});
|
||||
assert.deepEqual(await menu.allTextContents(), ['Target', 'Roadmap', 'Stage - 01 - Skills Adoption', 'Stage - 02 - Autonomous Agent']);
|
||||
assert.deepEqual(await menu.allTextContents(), ['Six-month strategy', 'Roadmap', 'One bounded experiment', 'Beyond six months']);
|
||||
assert((await menu.nth(0).getAttribute('href')).endsWith('/strategy/target-operating-model/'));
|
||||
assert((await menu.nth(1).getAttribute('href')).endsWith('/strategy/roadmap/'));
|
||||
assert.equal(await menu.filter({hasText:/^Target$/}).count(), 1);
|
||||
assert.equal(await menu.filter({hasText:/^Six-month strategy$/}).count(), 1);
|
||||
await page.screenshot({path:`${output}/${width}-${route ? 'target' : 'landing'}-navigation.png`,fullPage:true,animations:'disabled'});
|
||||
await menu.nth(1).click();
|
||||
await page.waitForURL('**/strategy/roadmap/');
|
||||
await page.getByRole('heading', {level:1,name:'Roadmap',exact:true}).waitFor();
|
||||
await page.goBack({waitUntil:'domcontentloaded'});
|
||||
await page.waitForURL('**/strategy/target-operating-model/');
|
||||
const iframe = page.locator(`.archify-panel--story > .story-${width > 700 ? 'desktop' : 'mobile'}`);
|
||||
await page.getByText('Conditional long-term Target operating model — not the six-month promise',{exact:true}).focus();
|
||||
await page.keyboard.press('Enter');
|
||||
const iframe = page.locator(`[data-diagram="strategy-target"] > .story-${width > 700 ? 'desktop' : 'mobile'}`);
|
||||
await iframe.scrollIntoViewIfNeeded();
|
||||
const frame = await (await iframe.elementHandle()).contentFrame();
|
||||
await frame.locator('svg[role="img"]').waitFor();
|
||||
@@ -77,8 +79,9 @@ const fs = require('node:fs');
|
||||
}
|
||||
assert(metrics.labels.every(n=>n.px>=14), JSON.stringify(metrics.labels));
|
||||
assert.deepEqual(metrics.overflow, []);
|
||||
await frame.locator('#btn-export').click();
|
||||
const [download] = await Promise.all([page.waitForEvent('download'), frame.locator('[data-format="svg"]').click()]);
|
||||
await frame.locator('#btn-export').focus(); await page.keyboard.press('Enter');
|
||||
await frame.locator('[data-format="svg"]').focus();
|
||||
const [download] = await Promise.all([page.waitForEvent('download'), page.keyboard.press('Enter')]);
|
||||
assert.equal(await download.failure(), null);
|
||||
const exportPath = `${output}/${width}-${route ? 'target' : 'landing'}.svg`;
|
||||
await download.saveAs(exportPath);
|
||||
|
||||
@@ -46,7 +46,7 @@ const fs = require('node:fs');
|
||||
await page.waitForURL(`${base}/eldorado-v1/documentation/strategy/measurement/supported-bundle-coverage/`);
|
||||
await page.getByRole('heading', {level:1, name:'Supported bundle coverage', exact:true}).waitFor();
|
||||
assert((await page.locator('article').innerText()).includes('Supported bundle coverage'));
|
||||
assert.equal(await page.locator('.breadcrumbs a').filter({hasText:'Stage - 01 - Skills Adoption'}).getAttribute('href'), '/eldorado-v1/documentation/strategy/stage-01-skills-adoption/');
|
||||
assert.equal(await page.locator('.breadcrumbs a').filter({hasText:'One bounded experiment'}).getAttribute('href'), '/eldorado-v1/documentation/strategy/stage-01-skills-adoption/');
|
||||
assert((await page.locator('.breadcrumbs').innerText()).includes('Measurement'));
|
||||
await open();
|
||||
await menu.getByRole('link', {name:'Supported bundle coverage', exact:true}).waitFor({state:'visible'});
|
||||
|
||||
@@ -15,8 +15,8 @@ const fs = require('node:fs');
|
||||
page.on('pageerror', error => errors.push(error.message));
|
||||
const response = await page.goto(`${base}/eldorado-v1/documentation/strategy/measurement/`, {waitUntil:'networkidle'});
|
||||
assert.equal(response.status(), 200);
|
||||
assert.equal(await page.locator('h1').innerText(), 'Skills Measurement');
|
||||
assert((await page.title()).startsWith('Skills Measurement |'));
|
||||
assert.equal(await page.locator('h1').innerText(), 'Measuring real output');
|
||||
assert((await page.title()).startsWith('Measuring real output |'));
|
||||
assert.equal(await page.locator('.strategy-content details').count(), 1);
|
||||
assert.equal(await page.locator('.strategy-content details[open]').count(), 0);
|
||||
assert((await page.locator('.strategy-content details summary').innerText()).includes('Implementation status'));
|
||||
@@ -28,7 +28,7 @@ const fs = require('node:fs');
|
||||
const menu = page.locator('.theme-doc-sidebar-menu .menu__link').filter({visible:true});
|
||||
await menu.first().waitFor({state:'visible'});
|
||||
const metrics = JSON.parse(fs.readFileSync('research/ai-adoption/measurement-migration.json','utf8')).metrics;
|
||||
assert.deepEqual(await menu.allTextContents(), ['Target','Roadmap','Stage - 01 - Skills Adoption','Measurement',...metrics.map(m => m.title),'Collection and safeguards','Run the synthetic measurement example','Baseline','Governance','Quality','Adoption','Maintenance','Stage - 02 - Autonomous Agent']);
|
||||
assert.deepEqual(await menu.allTextContents(), ['Six-month strategy','Roadmap','One bounded experiment','Measurement',...metrics.map(m => m.title),'Collection and safeguards','Run the synthetic measurement example','Baseline','Governance','Quality','Adoption','Maintenance','Beyond six months']);
|
||||
if (width < 700) await page.getByRole('button', {name:'Close navigation bar'}).click();
|
||||
const panel = page.locator('.archify-panel--story');
|
||||
const iframe = panel.locator(width > 700 ? '.story-desktop' : '.story-mobile');
|
||||
|
||||
@@ -6,10 +6,10 @@ const assert=require('node:assert/strict');
|
||||
const out=`.cache/skills-${process.argv[3]||'candidate'}`;fs.mkdirSync(out,{recursive:true});
|
||||
const browser=await chromium.launch({executablePath:process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE,args:['--no-sandbox']}); const results=[];
|
||||
try {
|
||||
for(const topic of ['measurement','baseline','governance','quality','adoption','maintenance','stage01','stage02']) for(const width of [1440,1024,390,320]) {
|
||||
for(const topic of ['six-months','measurement','baseline','governance','quality','adoption','maintenance','stage01','stage02']) for(const width of [1440,1024,390,320]) {
|
||||
console.log(`Checking ${topic} at ${width}px`);
|
||||
const page=await browser.newPage({viewport:{width,height:900},colorScheme:'light'});const errors=[];page.on('pageerror',e=>errors.push(e.message));
|
||||
const route=topic==='stage01'?'stage-01-skills-adoption':topic==='stage02'?'stage-02-autonomous-agent':['measurement','baseline'].includes(topic)?topic:`skills-${topic}`;
|
||||
const route=topic==='six-months'?'target-operating-model':topic==='stage01'?'stage-01-skills-adoption':topic==='stage02'?'stage-02-autonomous-agent':['measurement','baseline'].includes(topic)?topic:`skills-${topic}`;
|
||||
assert.equal((await page.goto(`${base}/eldorado-v1/documentation/strategy/${route}/`,{waitUntil:'networkidle'})).status(),200);
|
||||
const panel=page.locator('.archify-panel--skills');assert.equal(await panel.count(),1);
|
||||
const iframe=panel.locator(width>1100?'.story-desktop':'.story-mobile');await iframe.scrollIntoViewIfNeeded();
|
||||
|
||||
@@ -6,14 +6,14 @@ const fs = require('node:fs');
|
||||
const output = `.cache/strategy-navigation-${process.argv[3] || 'local'}`;
|
||||
fs.mkdirSync(output, {recursive:true});
|
||||
const prefix = '/eldorado-v1/documentation/strategy/';
|
||||
const first = 'Stage - 01 - Skills Adoption';
|
||||
const second = 'Stage - 02 - Autonomous Agent';
|
||||
const first = 'One bounded experiment';
|
||||
const second = 'Beyond six months';
|
||||
const topics = ['Measurement','Baseline','Governance','Quality','Adoption','Maintenance'];
|
||||
const metrics = JSON.parse(fs.readFileSync('research/ai-adoption/measurement-migration.json','utf8')).metrics;
|
||||
const childIds = [...metrics.map(m => m.docId),'measurement/collection-and-safeguards','measurement/synthetic-example'];
|
||||
const childTitles = [...metrics.map(m => m.title),'Collection and safeguards','Run the synthetic measurement example'];
|
||||
const ids = ['target-operating-model','roadmap','stage-01-skills-adoption','measurement',...childIds,'baseline','skills-governance','skills-quality','skills-adoption','skills-maintenance','stage-02-autonomous-agent'];
|
||||
const titles = ['Target','Roadmap',first,'Skills Measurement',...childTitles,'Baseline','Skills governance','Skills quality','Skills adoption','Skills maintenance',second];
|
||||
const titles = ['First six months as AI Architect','Roadmap',first,'Measuring real output',...childTitles,'Baseline','Skills governance','Skills quality','Skills adoption','Skills maintenance',second];
|
||||
const browser = await chromium.launch({headless:true, executablePath:process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE, args:['--no-sandbox']});
|
||||
const results = [];
|
||||
try {
|
||||
@@ -35,24 +35,24 @@ const fs = require('node:fs');
|
||||
assert.equal((await page.goto(`${base}${prefix}roadmap/`, {waitUntil:'networkidle'})).status(), 200);
|
||||
let menu = await openMenu();
|
||||
const visibleLabels = () => menu.locator('.menu__link').filter({visible:true}).allTextContents();
|
||||
assert.deepEqual(await visibleLabels(), ['Target','Roadmap',first,second]);
|
||||
assert.deepEqual(await visibleLabels(), ['Six-month strategy','Roadmap',first,second]);
|
||||
const category = menu.locator('.theme-doc-sidebar-item-category').filter({has:page.getByRole('link', {name:first, exact:true})});
|
||||
const caret = category.locator(':scope > .menu__list-item-collapsible > button.menu__caret');
|
||||
await caret.click();
|
||||
await category.getByRole('link', {name:'Governance', exact:true}).waitFor({state:'visible'});
|
||||
assert.deepEqual(await visibleLabels(), ['Target','Roadmap',first,...topics,second]);
|
||||
assert.deepEqual(await visibleLabels(), ['Six-month strategy','Roadmap',first,...topics,second]);
|
||||
assert.deepEqual(await category.locator('ul .menu__link').filter({visible:true}).allTextContents(), topics);
|
||||
const measurement = category.locator('.theme-doc-sidebar-item-category').filter({has:page.getByRole('link', {name:'Measurement', exact:true})});
|
||||
const reference = measurement.locator(':scope > .menu__list-item-collapsible > button.menu__caret');
|
||||
await reference.focus();
|
||||
await page.keyboard.press('Enter');
|
||||
await category.getByRole('link', {name:'Validated task success', exact:true}).waitFor({state:'visible'});
|
||||
assert.deepEqual(await visibleLabels(), ['Target','Roadmap',first,topics[0],...childTitles,...topics.slice(1),second]);
|
||||
assert.deepEqual(await visibleLabels(), ['Six-month strategy','Roadmap',first,topics[0],...childTitles,...topics.slice(1),second]);
|
||||
await reference.click();
|
||||
await page.screenshot({path:`${output}/${width}-expanded.png`, animations:'disabled'});
|
||||
await caret.click();
|
||||
await category.getByRole('link', {name:'Governance', exact:true}).waitFor({state:'hidden'});
|
||||
assert.deepEqual(await visibleLabels(), ['Target','Roadmap',first,second]);
|
||||
assert.deepEqual(await visibleLabels(), ['Six-month strategy','Roadmap',first,second]);
|
||||
await menu.getByRole('link', {name:first, exact:true}).click();
|
||||
await page.waitForURL(`${base}${prefix}stage-01-skills-adoption/`);
|
||||
await page.getByRole('heading', {level:1, name:first, exact:true}).waitFor();
|
||||
@@ -64,8 +64,7 @@ const fs = require('node:fs');
|
||||
assert.equal((await page.goto(`${base}${prefix}${id}/`, {waitUntil:'networkidle'})).status(), 200);
|
||||
assert.equal(new URL(page.url()).pathname, `${prefix}${id}/`);
|
||||
// Target has a longer canonical page heading but keeps its short navigation label.
|
||||
if (index) assert.equal(await page.locator('h1').innerText(), titles[index]);
|
||||
else assert((await page.locator('h1').innerText()).includes('Target'));
|
||||
assert.equal(await page.locator('h1').innerText(), titles[index]);
|
||||
const prev = page.locator('.pagination-nav__link--prev');
|
||||
const next = page.locator('.pagination-nav__link--next');
|
||||
if (index) assert.equal(await prev.getAttribute('href'), `${prefix}${id === 'baseline' ? 'measurement' : ids[index-1]}/`);
|
||||
@@ -76,7 +75,7 @@ const fs = require('node:fs');
|
||||
assert.equal(await page.locator('.breadcrumbs a').filter({hasText:first}).getAttribute('href'), `${prefix}stage-01-skills-adoption/`);
|
||||
menu = await openMenu();
|
||||
const expectedTopics = id === 'measurement' || id.startsWith('measurement/') ? [topics[0],...childTitles,...topics.slice(1)] : topics;
|
||||
assert.deepEqual(await visibleLabels(), ['Target','Roadmap',first,...expectedTopics,second]);
|
||||
assert.deepEqual(await visibleLabels(), ['Six-month strategy','Roadmap',first,...expectedTopics,second]);
|
||||
if (id.startsWith('measurement/')) assert.equal(await page.locator('.breadcrumbs a').filter({hasText:'Measurement'}).getAttribute('href'), `${prefix}measurement/`);
|
||||
await closeMenu();
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ const fs=require('node:fs');
|
||||
assert.equal(geometry.nodes.length,(source.components||source.nodes).length,id);
|
||||
for(const n of geometry.nodes) assert(n.x>=0 && n.y>=0 && n.right<=geometry.width+1 && n.bottom<=geometry.height+1,`${id} ${width} clipped ${JSON.stringify(n)} / ${geometry.height}`);
|
||||
const data=await page.locator('.strategy-content').evaluate(el=>({words:el.innerText.trim().split(/\s+/).length,overflow:document.documentElement.scrollWidth>innerWidth,openDetails:el.querySelectorAll('details[open]').length}));
|
||||
assert(data.words<=(id==='measurement'?1600:id==='roadmap'?600:550),id);assert(!data.overflow,id);assert.equal(data.openDetails,0,id);
|
||||
assert(data.words<=(id==='measurement'?1900:id==='roadmap'?1150:['index','target-operating-model'].includes(id)?850:750),id);assert(!data.overflow,id);assert.equal(data.openDetails,0,id);
|
||||
await page.evaluate(()=>scrollTo({top:0,behavior:'instant'}));await page.screenshot({path:`.cache/story-${label}/${width}-${id}.png`,fullPage:true});
|
||||
const opener=panel.getByRole('button',{name:/^Expand /});await opener.click();
|
||||
const close=panel.getByRole('button',{name:'Close full-screen diagram',exact:true});await close.waitFor({state:'visible'});
|
||||
|
||||
@@ -131,6 +131,9 @@ function inspectTypography({mobile}) {
|
||||
for (const width of [1440,390,320]) {
|
||||
const page = await browser.newPage({viewport:{width,height:1000}});
|
||||
await page.goto(`${base}/eldorado-v1/documentation/strategy/target-operating-model/`,{waitUntil:'networkidle'});
|
||||
await page.addStyleTag({content:'html {scroll-behavior:auto !important;}'});
|
||||
await page.getByText('Conditional long-term Target operating model — not the six-month promise',{exact:true}).focus();
|
||||
await page.keyboard.press('Enter');
|
||||
const panel = page.locator('[data-diagram="strategy-target"]');
|
||||
const iframe = panel.locator(`:scope > .story-${width > 700 ? 'desktop' : 'mobile'}`);
|
||||
await iframe.scrollIntoViewIfNeeded();
|
||||
@@ -141,10 +144,11 @@ function inspectTypography({mobile}) {
|
||||
await page.screenshot({path:`${output}/${width}-inline.png`,fullPage:true});
|
||||
const exported = [];
|
||||
for (const theme of ['light','dark']) {
|
||||
if (await frame.locator('html').getAttribute('data-theme') !== theme) await frame.locator('#btn-theme').click();
|
||||
if (await frame.locator('html').getAttribute('data-theme') !== theme) {await frame.locator('#btn-theme').focus(); await page.keyboard.press('Enter');}
|
||||
await frame.waitForFunction(t => document.documentElement.dataset.theme === t, theme);
|
||||
await frame.locator('#btn-export').click();
|
||||
const [download] = await Promise.all([page.waitForEvent('download'),frame.locator('[data-format="svg"]').click()]);
|
||||
await frame.locator('#btn-export').focus(); await page.keyboard.press('Enter');
|
||||
await frame.locator('[data-format="svg"]').focus();
|
||||
const [download] = await Promise.all([page.waitForEvent('download'),page.keyboard.press('Enter')]);
|
||||
assert.equal(await download.failure(),null);
|
||||
const path = `${output}/${width}-${theme}.svg`;
|
||||
await download.saveAs(path);
|
||||
@@ -157,6 +161,10 @@ function inspectTypography({mobile}) {
|
||||
const typography = await standalone.evaluate(inspectTypography,{mobile:width < 700});
|
||||
assert.deepEqual(geometry.errors,[]);
|
||||
assert.deepEqual(typography.errors,[]);
|
||||
assert(await standalone.locator('#eldorado-target-caption').evaluate(g=>{
|
||||
const v=g.ownerSVGElement.viewBox.baseVal;
|
||||
return [...g.querySelectorAll('text')].every(t=>{const b=t.getBBox();return b.x>=v.x&&b.y>=v.y&&b.x+b.width<=v.x+v.width&&b.y+b.height<=v.y+v.height;});
|
||||
}), 'Standalone proposed caption must fit the complete canvas');
|
||||
const background = await standalone.locator('rect.c-bg-rect').evaluate(n => getComputedStyle(n).fill);
|
||||
if (exported.length) assert.notEqual(background,exported[0].background,'standalone theme must change');
|
||||
// CDP captures SVG documents without Playwright's HTML-body screenshot wait.
|
||||
@@ -167,7 +175,7 @@ function inspectTypography({mobile}) {
|
||||
exported.push({theme,background,geometry,typography});
|
||||
await standalone.close();
|
||||
}
|
||||
await panel.getByRole('button',{name:/^Expand /}).click();
|
||||
await panel.getByRole('button',{name:/^Expand /}).focus(); await page.keyboard.press('Enter');
|
||||
const full = await (await panel.locator('dialog iframe').elementHandle()).contentFrame();
|
||||
await full.locator('svg[role="img"]').waitFor();
|
||||
// The existing fullscreen viewer always opens the radial desktop source.
|
||||
|
||||
Reference in new issue
Block a user