Expand drawing widths and quarantine live-feed test

This commit is contained in:
Chris Amow 2026-08-13 03:54:28 -05:00
parent 22a638cf73
commit 0e2d5fa2cb
5 changed files with 28 additions and 8 deletions

View file

@ -69,7 +69,7 @@ class LineCreate(BaseModel):
note: str = ""
hidden: bool = False
color: str = Field("#65b7cf", pattern=r"^#[0-9a-fA-F]{6}$")
line_width: int = Field(2, ge=1, le=4)
line_width: int = Field(2, ge=1, le=9)
cutoff_t: int | None = None
armed: bool = True
@ -86,7 +86,7 @@ class PriceAlertCreate(BaseModel):
note: str = ""
tf: Timeframe = Timeframe.D1
color: str = Field("#e0a34a", pattern=r"^#[0-9a-fA-F]{6}$")
line_width: int = Field(2, ge=1, le=4)
line_width: int = Field(2, ge=1, le=9)
class LinePatch(BaseModel):
@ -94,7 +94,7 @@ class LinePatch(BaseModel):
note: str | None = None
hidden: bool | None = None
color: str | None = Field(None, pattern=r"^#[0-9a-fA-F]{6}$")
line_width: int | None = Field(None, ge=1, le=4)
line_width: int | None = Field(None, ge=1, le=9)
anchor_t: int | None = None
anchor_p: float | None = None
slope: float | None = None

View file

@ -753,7 +753,7 @@ re-run is indistinguishable from a fix.
### 2026-08-11 — flaky browser cases quarantined
The four cases named above are skipped rather than allowed to make the full
The cases named above are skipped rather than allowed to make the full
suite nondeterministic. The symbol failure was reproduced: an older persisted,
off-screen symbol occupied the same edge position and intercepted the click
intended for the symbol created by the test. That test is unsound while it
@ -763,6 +763,13 @@ before a multi-step gesture, so they need stable fixture data or stronger
gesture-local targeting. The diagnostic capture case needs deterministic
display-media and upload-completion boundaries.
The live-edge viewport case joined the quarantine after the same pattern was
observed directly: its helper reads candle data and the visible range in
separate chart API calls while the live feed can update between them. It then
requires exact timestamp equality, so a legitimate new bar makes the assertion
compare two different instants. It needs one stable snapshot or a tolerance
that still catches the original ten-hour regression before it is sound.
These are explicit `node:test` skips with reasons, not deleted coverage. Re-enable
each case only after its stated external dependency is removed and repeated full
suite runs remain green.

View file

@ -66,7 +66,7 @@
<label>Label<input v-model.trim="drawName" placeholder="optional" aria-label="Trendline label"></label>
<div class="row">
<label>Colour<input type="color" v-model="drawColor" aria-label="Trendline colour"></label>
<label>Width<select v-model.number="drawWidth" aria-label="Trendline width"><option v-for="width in [1,2,3,4]" :value="width">{{ width }}px</option></select></label>
<label>Width<select v-model.number="drawWidth" aria-label="Trendline width"><option v-for="width in 9" :value="width">{{ width }}px</option></select></label>
</div>
<div class="row">
<!-- Side is inferred from the extreme you snap to, so it only has
@ -86,7 +86,7 @@
<label>Label<input v-model.trim="alertNote" placeholder="optional" aria-label="Level label"></label>
<div class="row">
<label>Colour<input type="color" v-model="levelColor" aria-label="Level colour"></label>
<label>Width<select v-model.number="levelWidth" aria-label="Level width"><option v-for="width in [1,2,3,4]" :value="width">{{ width }}px</option></select></label>
<label>Width<select v-model.number="levelWidth" aria-label="Level width"><option v-for="width in 9" :value="width">{{ width }}px</option></select></label>
</div>
<form class="row price-row" @submit.prevent="addPriceAlert">
<label>Price<input type="number" step="0.25" v-model.number="alertPrice" :placeholder="price == null ? '0.00' : price.toFixed(2)" aria-label="Level price"></label>
@ -223,7 +223,7 @@
</details>
<select :value="item.line.line_width || 2" aria-label="Drawing width"
@change="updateLineStyle(item.line, {line_width: Number($event.target.value)})">
<option v-for="width in [1,2,3,4]" :value="width">{{ width }}</option>
<option v-for="width in 9" :value="width">{{ width }}</option>
</select>
</div>
<div class="drawing-controls" @click.stop v-else>

View file

@ -139,7 +139,10 @@ test('diagnostic capture uploads a PNG and adds its capability ID to Events',
}
});
test('the viewport opens on the live edge, not in the past', { timeout: 180000 }, async () => {
test('the viewport opens on the live edge, not in the past', {
timeout: 180000,
skip: 'quarantined: chart data and viewport are sampled separately while the live feed advances',
}, async () => {
await withChart(async page => {
const state = await chartState(page);
assert.ok(state.bars > 0, 'the chart loaded no bars at all');

View file

@ -10,6 +10,9 @@ test('editing a drawing name with Backspace or Delete cannot delete the drawing'
const label = `e2e rename ${Date.now()}`;
const box = await chartBox(page);
await armTool(page, 'Trendline');
assert.deepEqual(await page.locator('select[aria-label="Trendline width"] option').allTextContents(),
['1px', '2px', '3px', '4px', '5px', '6px', '7px', '8px', '9px']);
await page.selectOption('select[aria-label="Trendline width"]', '9');
await page.fill('input[aria-label="Trendline label"]', label);
const first = at(box, 0.42, 0.55);
const second = at(box, 0.62, 0.40);
@ -31,11 +34,16 @@ test('editing a drawing name with Backspace or Delete cannot delete the drawing'
}, label);
assert.ok(created, 'the trendline was not created');
assert.ok((await drawingIds(page)).includes(created), 'the trendline was not persisted');
assert.equal(await page.evaluate(id =>
window.__chart.levels.find(level => level.id === id)?.line_width, created), 9,
'the 9px trendline width was not persisted');
await page.fill('input[aria-label="Filter drawings by text"]', label);
const input = page.locator('input[aria-label="Drawing name"]');
assert.equal(await input.count(), 1, 'the unique drawing filter did not isolate the test line');
const row = page.locator('.trendline-row');
assert.deepEqual(await row.locator('select[aria-label="Drawing width"] option').allTextContents(),
['1', '2', '3', '4', '5', '6', '7', '8', '9']);
const rowBox = await row.boundingBox();
assert.ok(rowBox.height <= 48, `drawing row is still ${rowBox.height}px tall`);
assert.equal(await row.locator('.drawing-state .fa-bell').count(), 1,
@ -91,6 +99,8 @@ test('a price level selects and focuses in both directions', { timeout: 180000 }
const label = `e2e level focus ${Date.now()}`;
const price = await page.evaluate(() => window.__chart.bars.at(-1).c);
await armTool(page, 'Price level');
assert.deepEqual(await page.locator('select[aria-label="Level width"] option').allTextContents(),
['1px', '2px', '3px', '4px', '5px', '6px', '7px', '8px', '9px']);
await page.fill('input[aria-label="Level label"]', label);
await page.fill('input[aria-label="Level price"]', String(price));
await page.locator('.price-row button[type="submit"]').click();