import { test } from 'node:test'; import assert from 'node:assert/strict'; import { withChart, selectTimeframe, assertNoPageErrors } from './helpers.mjs'; const volumeState = page => page.evaluate(() => { const chart = window.__chart; const candles = chart.candles.data(); const volume = chart.volume.data(); return { candleTimes: candles.map(point => point.time), volumeTimes: volume.map(point => point.time), values: volume.map(point => point.value), scaleId: chart.volume.options().priceScaleId, scale: chart.chart.priceScale('volume').options(), }; }); test('volume follows every candle across timeframe changes on its own scale', { timeout: 240000 }, async () => { await withChart(async page => { await selectTimeframe(page, '1m'); const minute = await volumeState(page); assert.deepEqual(minute.volumeTimes, minute.candleTimes, '1m volume timestamps are not one-for-one with candle timestamps'); assert.ok(minute.values.some(value => value > 0), '1m volume contains no non-zero values'); assert.equal(minute.scaleId, 'volume', 'volume shares a price scale with another series'); assert.equal(minute.scale.visible, false, 'the dedicated volume scale became visible'); assert.ok(minute.scale.scaleMargins.top >= 0.75, 'volume is no longer confined to the bottom of the chart'); await selectTimeframe(page, '1h'); const hourly = await volumeState(page); assert.deepEqual(hourly.volumeTimes, hourly.candleTimes, '1h volume timestamps are not one-for-one with candle timestamps'); assert.ok(hourly.values.some(value => value > 0), '1h volume contains no non-zero values'); assert.notDeepEqual(hourly.volumeTimes, minute.volumeTimes, 'volume data did not change with the candle timeframe'); assert.equal(hourly.scaleId, 'volume', 'volume left its dedicated scale after switching'); assertNoPageErrors(page, assert); }); });