const assert=require('node:assert/strict'); const fs=require('node:fs'); const {launchBrowser,isolatedUser,signIn}=require('./support/browser.cjs'); 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)); // Sandbox 9 belongs to this suite; workspaces cannot be created, so the fixture configures it. const tester=await isolatedUser({sandbox:9,prefix:'contact-approval',display:'Contact planner'}); await signIn(page,tester.username,tester.password); await page.getByLabel('Workspace',{exact:true}).waitFor(); const fixture=await page.evaluate(async()=>{ const a=Alpine.$data(document.body); const r=(await a.api('/api/workspaces/'+a.workspace.id)).workspace; const start=a.addDays(a.today(),2),contact=crypto.randomUUID(); const doc=r.document; doc.people.push({id:contact,user_id:null,display_name:'Email colleague',email:'colleague@example.com',country:'CY'}); doc.schedules=[{id:crypto.randomUUID(),name:'Contact duty',type:'rotation',participants:[a.user.id],anchor:start,shift_days:7,handover:'11:00:00'}]; await a.api('/api/workspaces/'+r.id+'/config','PUT',{revision:r.revision,document:doc}); return {workspace:r.id,start,contact}; }); await page.goto(base+'/?workspace='+fixture.workspace); await page.locator('[data-duty-date="'+fixture.start+'"]').click(); const dialog=page.getByRole('dialog'); await dialog.getByLabel('Search colleagues').fill('colleague@example.com'); await dialog.getByRole('button',{name:'Email colleague',exact:true}).click(); const apply=dialog.getByRole('button',{name:'Apply now',exact:true}); await apply.waitFor(); await page.waitForFunction(()=>Alpine.$data(document.body).canSendRequest); assert.equal(await apply.isEnabled(),true); await dialog.getByText('Applies immediately. No approval needed.',{exact:true}).waitFor(); fs.mkdirSync('test-results',{recursive:true}); await page.screenshot({path:'test-results/contact-approval.png'}); await apply.click(); await dialog.waitFor({state:'hidden'}); const request=await page.evaluate(()=>Alpine.$data(document.body).doc.requests.at(-1)); assert.equal(request.status,'applied'); assert.equal(request.forced_by,null); assert.deepEqual(request.required_approvers,[]); await page.reload(); await page.waitForFunction(()=>Alpine.$data(document.body).doc?.requests.length); assert.match(await page.locator('[data-duty-date="'+fixture.start+'"]').innerText(),/Email/); assert.equal(await page.evaluate(id=>Alpine.$data(document.body).doc.requests.at(-1).legs[0].to_user,fixture.contact),fixture.contact); assert.deepEqual(errors,[]); console.log('PASS: email contact preview, immediate unforced save, calendar persistence, no JavaScript errors'); }finally{await browser.close();} })().catch(e=>{console.error(e);process.exitCode=1;});