119 lines
5.4 KiB
JavaScript
119 lines
5.4 KiB
JavaScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { withChart, assertNoPageErrors } from './helpers.mjs';
|
|
|
|
test('touch tap selects a drawing and horizontal and vertical pinches scale only their own axes',
|
|
{ timeout: 180000 }, async () => {
|
|
await withChart(async page => {
|
|
const label = `e2e touch ${Date.now()}`;
|
|
const created = await page.evaluate(async name => {
|
|
const price = window.__chart.bars.at(-1).c;
|
|
const response = await fetch('/api/lines/price', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ price, note: name }),
|
|
});
|
|
return response.json();
|
|
}, label);
|
|
await page.waitForFunction(id =>
|
|
window.__chart.levels.some(level => level.id === id), created.id);
|
|
|
|
const cdp = await page.context().newCDPSession(page);
|
|
const geometry = await page.evaluate(id => {
|
|
const chart = window.__chart;
|
|
const level = chart.levels.find(value => value.id === id);
|
|
const plot = chart.plotCanvas().getBoundingClientRect();
|
|
return {
|
|
tap: { x: plot.left + plot.width * 0.5, y: plot.top + chart.candles.priceToCoordinate(level.anchor_p) },
|
|
horizontal: {
|
|
x1: plot.left + plot.width * 0.35, y1: plot.top + plot.height * 0.5,
|
|
x2: plot.left + plot.width * 0.65, y2: plot.top + plot.height * 0.5,
|
|
},
|
|
vertical: {
|
|
x1: plot.left + plot.width * 0.5, y1: plot.top + plot.height * 0.35,
|
|
x2: plot.left + plot.width * 0.5, y2: plot.top + plot.height * 0.65,
|
|
},
|
|
};
|
|
}, created.id);
|
|
|
|
await cdp.send('Input.dispatchTouchEvent', {
|
|
type: 'touchStart', touchPoints: [{ ...geometry.tap, id: 1 }],
|
|
});
|
|
await cdp.send('Input.dispatchTouchEvent', { type: 'touchEnd', touchPoints: [] });
|
|
await page.waitForFunction(id => window.__chart.selectedLineId === id, created.id);
|
|
assert.match(await page.locator('.chart-tooltip').textContent(), new RegExp(label));
|
|
|
|
const state = () => page.evaluate(() => {
|
|
const chart = window.__chart;
|
|
const range = chart.chart.timeScale().getVisibleLogicalRange();
|
|
return {
|
|
timeFrom: range.from,
|
|
timeTo: range.to,
|
|
timeSpan: range.to - range.from,
|
|
priceSpan: Math.abs(chart.candles.coordinateToPrice(80) - chart.candles.coordinateToPrice(500)),
|
|
pageScale: window.visualViewport?.scale || 1,
|
|
};
|
|
});
|
|
const pinch = async (points, axis) => {
|
|
await cdp.send('Input.dispatchTouchEvent', {
|
|
type: 'touchStart',
|
|
touchPoints: [
|
|
{ x: points.x1, y: points.y1, id: 1 },
|
|
{ x: points.x2, y: points.y2, id: 2 },
|
|
],
|
|
});
|
|
for (let step = 1; step <= 8; step += 1) {
|
|
const delta = step * 8;
|
|
await cdp.send('Input.dispatchTouchEvent', {
|
|
type: 'touchMove',
|
|
touchPoints: [
|
|
{ x: points.x1 - (axis === 'x' ? delta : 0), y: points.y1 - (axis === 'y' ? delta : 0), id: 1 },
|
|
{ x: points.x2 + (axis === 'x' ? delta : 0), y: points.y2 + (axis === 'y' ? delta : 0), id: 2 },
|
|
],
|
|
});
|
|
}
|
|
await cdp.send('Input.dispatchTouchEvent', { type: 'touchEnd', touchPoints: [] });
|
|
await page.waitForTimeout(300);
|
|
};
|
|
|
|
const before = await state();
|
|
await pinch(geometry.horizontal, 'x');
|
|
const horizontal = await state();
|
|
|
|
assert.notEqual(Math.round(horizontal.timeSpan), Math.round(before.timeSpan),
|
|
'horizontal pinch did not change the time scale');
|
|
assert.ok(Math.abs(horizontal.priceSpan - before.priceSpan) < 0.1,
|
|
`horizontal pinch changed the price scale (${before.priceSpan} to ${horizontal.priceSpan})`);
|
|
|
|
await pinch(geometry.vertical, 'y');
|
|
const vertical = await state();
|
|
assert.ok(Math.abs(vertical.priceSpan - horizontal.priceSpan) > 0.1,
|
|
'vertical pinch did not change the price scale');
|
|
assert.ok(Math.abs(vertical.timeSpan - horizontal.timeSpan) < 0.1,
|
|
'vertical pinch changed the time scale');
|
|
assert.equal(vertical.pageScale, before.pageScale, 'pinch zoomed the browser page');
|
|
|
|
const plot = await page.evaluate(() => {
|
|
const rect = window.__chart.plotCanvas().getBoundingClientRect();
|
|
return { left: rect.left, top: rect.top, width: rect.width, height: rect.height };
|
|
});
|
|
await cdp.send('Input.dispatchTouchEvent', {
|
|
type: 'touchStart',
|
|
touchPoints: [{ x: plot.left + plot.width * 0.5, y: plot.top + plot.height * 0.5, id: 1 }],
|
|
});
|
|
for (let step = 1; step <= 8; step += 1) {
|
|
await cdp.send('Input.dispatchTouchEvent', {
|
|
type: 'touchMove',
|
|
touchPoints: [{ x: plot.left + plot.width * 0.5 + step * 10, y: plot.top + plot.height * 0.5, id: 1 }],
|
|
});
|
|
}
|
|
await cdp.send('Input.dispatchTouchEvent', { type: 'touchEnd', touchPoints: [] });
|
|
await page.waitForTimeout(300);
|
|
const panned = await state();
|
|
assert.ok(Math.abs(panned.timeSpan - vertical.timeSpan) < 0.1,
|
|
'one-finger pan changed the time zoom');
|
|
assert.ok(Math.abs(panned.timeFrom - vertical.timeFrom) > 0.5,
|
|
'one-finger horizontal drag did not pan the chart');
|
|
assertNoPageErrors(page, assert);
|
|
}, { viewport: { width: 1200, height: 800 }, hasTouch: true, isMobile: true });
|
|
});
|