Files
meguri/tests/browser-account-person.cjs
T

44 lines
3.4 KiB
JavaScript
Raw Normal View History

2026-10-07 15:30:31 +01:00
const assert=require('node:assert/strict');
const fs=require('node:fs');
const {launchBrowser,isolatedUser,signIn}=require('./support/browser.cjs');
2026-10-07 15:30:31 +01:00
const base=process.env.MEGURI_BROWSER_URL||'http://127.0.0.1:3000';
assert(['localhost','127.0.0.1'].includes(new URL(base).hostname));
(async()=>{
const browser=await launchBrowser();
try {
const page=await browser.newPage({locale:'en-US',viewport:{width:1280,height:1000}});
const errors=[];page.on('pageerror',e=>errors.push(e.message));
// Accounts are created by the instance administrator (the email is entered in mixed case and stored normalized).
const email='account-person-'+Date.now()+'@example.com';
const tester=await isolatedUser({sandbox:8,prefix:'account-person',display:'Account person',email:email.toUpperCase()});
await signIn(page,tester.username,tester.password);
2026-10-07 15:30:31 +01:00
const dialog=page.getByRole('dialog');
await page.waitForFunction(()=>Alpine.$data(document.body).workspace);
// A rotation that plans the account saves its Person (id = account id, email from the account) into the document.
await page.evaluate(async()=>{const a=Alpine.$data(document.body),doc=structuredClone(Alpine.raw(a.doc)),me=a.people.find(p=>p.id===a.user.id);delete me.username;doc.people=[me];doc.schedules=[{id:crypto.randomUUID(),name:'Own rotation',type:'rotation',participants:[a.user.id],anchor:a.today(),shift_days:7,handover:'11:00:00'}];await a.api(a.endpoint('/config'),'PUT',{revision:a.workspace.revision,document:doc});await a.loadWorkspace();});
2026-10-07 15:30:31 +01:00
const state=await page.evaluate(()=>{const a=Alpine.$data(document.body);return {user:a.user,person:a.doc.people.find(p=>p.id===a.user.id)};});
assert.equal(state.user.email,email);
assert.equal(state.user.user_id,state.user.id);
assert.equal(state.person.email,email);
assert.equal(state.person.id,state.user.id);
await page.evaluate(()=>Alpine.$data(document.body).open('account'));
assert.equal(await dialog.getByLabel('Email address',{exact:true}).inputValue(),email);
assert.equal(await dialog.getByLabel('Email address',{exact:true}).isEditable(),false);
await dialog.getByLabel('Display name',{exact:true}).fill('Updated profile name');
await dialog.getByRole('button',{name:'Save changes',exact:true}).click();
await dialog.waitFor({state:'hidden'});
await page.reload();
await page.waitForFunction(()=>Alpine.$data(document.body).doc?.people.length);
assert.equal(await page.evaluate(()=>{const a=Alpine.$data(document.body);return a.doc.people.find(p=>p.id===a.user.id).display_name;}),'Updated profile name');
await page.evaluate(()=>{const a=Alpine.$data(document.body);a.open('rotation');a.editPerson(a.user.id);});
const details=page.getByRole('region',{name:'Choose a person'});
assert.equal(await details.getByLabel('Email for JSM lookup',{exact:true}).inputValue(),email);
assert.equal(await details.getByLabel('Email for JSM lookup',{exact:true}).isEditable(),false);
await page.setViewportSize({width:390,height:844});
fs.mkdirSync('test-results',{recursive:true});
await page.screenshot({path:'test-results/account-person-mobile.png'});
assert(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth));
assert.deepEqual(errors,[]);
console.log('PASS: required email, normalized account-owned Person, profile persistence, readonly scheduling identity, mobile');
}finally{await browser.close();}
})().catch(e=>{console.error(e);process.exitCode=1;});