Workspaces, group mappings and sign-in methods now come from a configuration file synchronized at startup; workspaces dropped from it are disabled, never deleted. Instance administrators (a new role) see and help every workspace and may delete disabled ones; workspace administrators and employees are derived from the user's groups at every SSO sign-in or administrator edit, and the employee permission set belongs to the workspace. Self-registration is gone: users come from SSO (only when their groups map) or from the administrator. Break-glass bootstrap accounts get an HMAC-derived hourly password that all replicas agree on. First SSO sign-in links a matching email contact to the user. The demo runs on the same model with a generated per-start password. Co-Authored-By: Claude <noreply@anthropic.com>
2 lines
1.5 KiB
JavaScript
2 lines
1.5 KiB
JavaScript
const assert=require('node:assert/strict');(async()=>{const b=await require('./support/browser.cjs').launchBrowser();try{const p=await b.newPage({viewport:{width:1440,height:1050}}),errors=[];p.on('pageerror',e=>errors.push(e.message));await p.goto('http://127.0.0.1:3000/?view=configuration');await p.getByLabel('Username',{exact:true}).fill('alice');await p.getByLabel('Password',{exact:true}).fill(await require('./support/browser.cjs').demoPassword());await p.getByRole('button',{name:'Sign in',exact:true}).click();await p.locator('.resource-row').first().waitFor();await p.getByRole('heading',{name:'Schedule setup',exact:true}).click();for(const [kind,index] of [['schedules',0],['schedules',1],['escalations',0],['routes',0]]){const row=p.locator('[data-resource-kind='+kind+']').nth(index);await row.locator('summary').click();await row.locator('.resource-widget').waitFor();assert(await row.locator('.widget-node').count()>0);await row.screenshot({path:'test-results/resource-'+kind+'-'+index+'.png'});await p.setViewportSize({width:390,height:844});await row.screenshot({path:'test-results/resource-'+kind+'-'+index+'-mobile.png'});assert((await row.boundingBox()).width<390);await p.setViewportSize({width:1440,height:1050});await row.locator('summary').click();}assert.deepEqual(errors,[]);console.log('PASS shared resource rows, schedule variants, escalation, routing, desktop and mobile');}finally{await b.close();}})().catch(e=>{console.error(e);process.exitCode=1;});
|