Ground Bean Bro in displayed temperatures, stream replies, and add activity calendar
Test and deploy / test-and-deploy (push) Successful in 1m19s

This commit is contained in:
snowspeeder committed 2026-09-07 06:38:16 -04:00
1 parent a72aec9f86
commit d96ed22de1
16 files changed
+551 -484

No files matched your search

+71 -17
View File
@@ -613,7 +613,7 @@ test(
},
);
test(
"browser: coffee history compares measured curves and quick tasting persists",
"browser: quick tasting persists and removed coffee history redirects to calendar",
browserOptions,
async (t) => {
const { page, base, create, db, errors } = await session(t);
@@ -666,22 +666,12 @@ test(
"coffee:" + warningPlan().fields["0.1"].toLowerCase(),
),
);
await page.getByRole("heading", { name: "Your favorite batch" }).waitFor();
await page
.getByRole("checkbox", { name: "Compare Batch 1", exact: true })
.check();
await page
.getByRole("checkbox", { name: "Compare Batch 2", exact: true })
.check();
await page
.getByRole("button", { name: "Compare selected batches" })
.click();
await page
.getByRole("img", {
name: "Measured roast curves, Fahrenheit versus time",
})
.waitFor();
assert.equal(await page.locator(".comparison-chart polyline").count(), 2);
await page.getByRole("heading", { name: "Activity calendar", exact:true }).waitFor();
await page.getByRole("heading", { name: "Activity log", exact:true }).waitFor();
assert.equal(new URL(page.url()).pathname,"/home");
await page.goto(base + "/roasts?roast=" + first);
await page.locator('#after-form [name="favorite"]').waitFor();
assert.equal(await page.locator('#after-form [name="favorite"]').inputValue(),"yes");
assert.deepEqual(errors, []);
},
);
@@ -761,3 +751,67 @@ test("browser: deleting a plan confirms in-page, supports retry, and preserves r
assert.deepEqual(remaining.plan_snapshot,plan);
assert.deepEqual(errors,[]);
});
test("browser: Bean Bro displays live text before completion and calendar links to activity",browserOptions,async(t)=>{
let release;
const gate=new Promise(r=>{release=r;});t.after(()=>release());
const {page,base,create,db,errors}=await session(t,{runPlanChat:async({onText})=>{
onText?.("First crack is shown at 392°F");
await gate;
return {reply:"First crack is shown at 392°F as an illustrative reference.",suggestions:[],model:"test:stream"};
}});
const saved=await create(warningPlan());
await page.goto(base+"/app?plan="+saved.id);
await page.locator("#chat-input").fill("What is the planned first crack temperature?");
await page.locator("#chat-send").click();
await page.locator("#chat-thread .assistant").filter({hasText:"First crack is shown at 392°F"}).waitFor();
assert.equal(await page.locator("#chat-send").isDisabled(),true);
assert.equal(await page.locator(".proposal-card").count(),0);
await page.screenshot({path:"/tmp/bean-bro-streaming.png"});
release();
await page.waitForFunction(()=>!document.getElementById("chat-send").disabled);
await page.locator("#chat-thread .assistant").filter({hasText:"illustrative reference"}).waitFor();
const owner=(await db.query("SELECT user_id FROM roast_plans WHERE id=$1",[saved.id])).rows[0].user_id;
const roast=(await db.query("INSERT INTO actual_roasts(user_id,roast_plan_id,filename,original_content,parsed,evaluation_status) VALUES($1,$2,'Burundi.alog','{}',$3,'failed') RETURNING id",[owner,saved.id,{roast:{title:"Burundi · Light & fruity",roastDate:"2026-09-05"},curve:[],derived:{}}])).rows[0];
await db.query("INSERT INTO cupping_sessions(user_id,roast_plan_id,data,created_at) VALUES($1,$2,$3,'2026-09-07')",[owner,saved.id,{}]);
const brew=(await db.query("INSERT INTO brews(user_id,method,brewed_at) VALUES($1,'v60','2026-09-08T12:00:00Z') RETURNING id",[owner])).rows[0];
await page.goto(base+"/home?month=2026-09");
await page.getByRole("heading",{name:"Activity log",exact:true}).waitFor();
assert.equal(await page.getByRole("link",{name:"Coffee history",exact:true}).count(),0);
assert.equal(await page.getByRole("link",{name:"Today",exact:true}).count(),0);
await page.screenshot({path:"/tmp/activity-calendar-desktop.png",fullPage:true,animations:"disabled"});
await page.getByRole("combobox",{name:"Activity type"}).selectOption("roast");
assert.equal(await page.locator(".calendar-agenda .calendar-log-row").count(),1);
await page.getByRole("combobox",{name:"Activity type"}).selectOption("");
await page.setViewportSize({width:390,height:844});
await page.reload();
await page.getByRole("heading",{name:"Activity log",exact:true}).waitFor();
await page.screenshot({path:"/tmp/activity-calendar-mobile.png",fullPage:true});
assert.equal(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth),true);
await page.locator('.calendar-agenda a[href="/roasts?roast='+roast.id+'"]').click();
await page.getByRole("heading",{name:"Quick taste",exact:true}).waitFor();
await page.goto(base+"/brews?brew="+brew.id);
await page.getByRole("heading",{name:"Edit brew",exact:true}).waitFor();
assert.deepEqual(errors,[]);
});
test("browser: an interrupted Bean Bro stream keeps partial text, restores the question and allows retry",browserOptions,async(t)=>{
let attempt=0;
const {page,base,create,errors}=await session(t,{runPlanChat:async({onText})=>{
onText?.("First crack is shown at 392°F.");
if(++attempt===1)throw new Error("Provider disconnected");
return {reply:"First crack is shown at 392°F; this is illustrative.",suggestions:[]};
}});
const saved=await create(warningPlan());
await page.goto(base+"/app?plan="+saved.id);
await page.locator("#chat-input").fill("Explain first crack");
await page.locator("#chat-send").click();
await page.locator("#chat-thread").getByText(/Response interrupted/).waitFor();
assert.equal(await page.locator("#chat-input").inputValue(),"Explain first crack");
assert.equal(await page.locator("#chat-send").isDisabled(),false);
assert.match(await page.locator("#chat-thread").innerText(),/392°F/);
await page.locator("#chat-send").click();
await page.locator("#chat-thread .assistant").filter({hasText:"this is illustrative"}).waitFor();
assert.equal(await page.locator("#chat-thread .user").count(),1);
assert.deepEqual(errors,[]);
});