| import { test, expect, type Page } from '@playwright/test' |
| import { setupSite, populateStats, addGoal } from '../fixtures' |
|
|
| type MetricCase = { |
| selector: string |
| expectedMetricLabel: string |
| expectedBuckets: BucketExpectation[] |
| } |
| type BucketExpectation = [ |
| bucketIndex: number, |
| timeLabel: string, |
| metricValue: string |
| ] |
|
|
| const MAIN_LINE = 'path.stroke-indigo-500[data-testid="graph-line"]' |
|
|
| async function hoverAndReadTooltip(page: Page, bucketIndex: number) { |
| await page.getByTestId(`graph-dot-series-1-bucket-${bucketIndex}`).hover() |
| const tooltip = page.getByTestId('graph-tooltip') |
| await expect(tooltip).toBeVisible() |
| return { |
| metricLabel: await tooltip.getByTestId('metric-label').innerText(), |
| mainTimeLabel: await tooltip.getByTestId('main-time-label').innerText(), |
| mainValue: await tooltip.getByTestId('main-value').innerText() |
| } |
| } |
|
|
| test.describe('plotting all metrics', () => { |
| |
| test.use({ locale: 'en-GB' }) |
|
|
| test('default view', async ({ page, request }) => { |
| const { domain } = await setupSite({ page, request }) |
|
|
| await populateStats({ |
| request, |
| domain, |
| events: [ |
| { |
| user_id: 1, |
| name: 'pageview', |
| pathname: '/', |
| timestamp: '2021-01-01 00:00:00' |
| }, |
| { |
| user_id: 1, |
| name: 'pageview', |
| pathname: '/page1', |
| timestamp: '2021-01-01 00:10:00' |
| }, |
| { |
| user_id: 1, |
| name: 'pageview', |
| pathname: '/page2', |
| timestamp: '2021-01-01 00:20:00' |
| }, |
| { |
| user_id: 2, |
| name: 'pageview', |
| pathname: '/', |
| timestamp: '2021-01-01 05:00:00' |
| } |
| ] |
| }) |
|
|
| await page.goto('/' + domain + '?period=day&date=2021-01-01', { |
| waitUntil: 'commit' |
| }) |
|
|
| const graphLine = page.locator(MAIN_LINE) |
| await expect(graphLine).toBeVisible() |
|
|
| const metricCases: MetricCase[] = [ |
| { |
| selector: '#visitors', |
| expectedMetricLabel: 'UNIQUE VISITORS', |
| expectedBuckets: [ |
| [0, '00:00', '1'], |
| [1, '01:00', '0'], |
| [5, '05:00', '1'] |
| ] |
| }, |
| { |
| selector: '#visits', |
| expectedMetricLabel: 'TOTAL VISITS', |
| expectedBuckets: [ |
| [0, '00:00', '1'], |
| [1, '01:00', '0'], |
| [5, '05:00', '1'] |
| ] |
| }, |
| { |
| selector: '#pageviews', |
| expectedMetricLabel: 'TOTAL PAGEVIEWS', |
| expectedBuckets: [ |
| [0, '00:00', '3'], |
| [1, '01:00', '0'], |
| [5, '05:00', '1'] |
| ] |
| }, |
| { |
| selector: '#views_per_visit', |
| expectedMetricLabel: 'VIEWS PER VISIT', |
| expectedBuckets: [ |
| [0, '00:00', '3'], |
| [1, '01:00', '0'], |
| [5, '05:00', '1'] |
| ] |
| }, |
| { |
| selector: '#bounce_rate', |
| expectedMetricLabel: 'BOUNCE RATE', |
| expectedBuckets: [ |
| [0, '00:00', '0%'], |
| [1, '01:00', '0%'], |
| [5, '05:00', '100%'] |
| ] |
| }, |
| { |
| selector: '#visit_duration', |
| expectedMetricLabel: 'VISIT DURATION', |
| expectedBuckets: [ |
| [0, '00:00', '20m 00s'], |
| [1, '01:00', '-'], |
| [5, '05:00', '0s'] |
| ] |
| } |
| ] |
|
|
| for (const { |
| selector, |
| expectedMetricLabel, |
| expectedBuckets |
| } of metricCases) { |
| await test.step(expectedMetricLabel, async () => { |
| await page.locator(selector).click() |
| await expect(graphLine).toBeVisible() |
|
|
| for (const [bucketIndex, timeLabel, metricValue] of expectedBuckets) { |
| const tooltipInfo = await hoverAndReadTooltip(page, bucketIndex) |
| expect(tooltipInfo.metricLabel).toBe(expectedMetricLabel) |
| expect( |
| tooltipInfo.mainTimeLabel, |
| `Wrong time label for ${expectedMetricLabel}` |
| ).toBe(timeLabel) |
| expect( |
| tooltipInfo.mainValue, |
| `Wrong metric value for ${expectedMetricLabel} in ${timeLabel}` |
| ).toBe(metricValue) |
| } |
| }) |
| } |
| }) |
|
|
| test('goal-filtered view', async ({ page, request }) => { |
| const goalName = 'Signup' |
| const { domain } = await setupSite({ page, request }) |
|
|
| await addGoal({ request, domain, params: { event_name: goalName } }) |
|
|
| await populateStats({ |
| request, |
| domain, |
| events: [ |
| { |
| user_id: 1, |
| name: 'pageview', |
| timestamp: '2021-01-01 00:00:00' |
| }, |
| { |
| user_id: 2, |
| name: goalName, |
| timestamp: '2021-01-01 10:00:00' |
| }, |
| { |
| user_id: 2, |
| name: goalName, |
| timestamp: '2021-01-01 10:10:00' |
| }, |
| { |
| user_id: 4, |
| name: 'pageview', |
| timestamp: '2021-01-01 10:00:00' |
| }, |
| { |
| user_id: 5, |
| name: goalName, |
| timestamp: '2021-01-01 23:00:00' |
| } |
| ] |
| }) |
|
|
| await page.goto( |
| '/' + domain + '?period=day&date=2021-01-01&f=is,goal,Signup', |
| { waitUntil: 'commit' } |
| ) |
|
|
| const graphLine = page.locator(MAIN_LINE) |
| await expect(graphLine).toBeVisible() |
|
|
| const metricCases: MetricCase[] = [ |
| { |
| selector: '#visitors', |
| expectedMetricLabel: 'UNIQUE CONVERSIONS', |
| expectedBuckets: [ |
| [0, '00:00', '0'], |
| [1, '01:00', '0'], |
| [10, '10:00', '1'], |
| [23, '23:00', '1'] |
| ] |
| }, |
| { |
| selector: '#events', |
| expectedMetricLabel: 'TOTAL CONVERSIONS', |
| expectedBuckets: [ |
| [0, '00:00', '0'], |
| [1, '01:00', '0'], |
| [10, '10:00', '2'], |
| [23, '23:00', '1'] |
| ] |
| }, |
| { |
| selector: '#conversion_rate', |
| expectedMetricLabel: 'CONVERSION RATE', |
| expectedBuckets: [ |
| [0, '00:00', '0%'], |
| [1, '01:00', '0%'], |
| [10, '10:00', '50%'], |
| [23, '23:00', '100%'] |
| ] |
| } |
| ] |
|
|
| for (const { |
| selector, |
| expectedMetricLabel, |
| expectedBuckets |
| } of metricCases) { |
| await test.step(expectedMetricLabel, async () => { |
| await page.locator(selector).click() |
| await expect(graphLine).toBeVisible() |
|
|
| for (const [bucketIndex, timeLabel, metricValue] of expectedBuckets) { |
| const tooltipInfo = await hoverAndReadTooltip(page, bucketIndex) |
| expect(tooltipInfo.metricLabel).toBe(expectedMetricLabel) |
| expect( |
| tooltipInfo.mainTimeLabel, |
| `Wrong time label for ${expectedMetricLabel}` |
| ).toBe(timeLabel) |
| expect( |
| tooltipInfo.mainValue, |
| `Wrong metric value for ${expectedMetricLabel} in ${timeLabel}` |
| ).toBe(metricValue) |
| } |
| }) |
| } |
| }) |
|
|
| test('page-filtered view', async ({ page, request }) => { |
| const { domain } = await setupSite({ page, request }) |
|
|
| await populateStats({ |
| request, |
| domain, |
| events: [ |
| { |
| user_id: 1, |
| name: 'pageview', |
| pathname: '/one', |
| timestamp: '2021-01-01 00:00:00' |
| }, |
| { |
| user_id: 2, |
| name: 'pageview', |
| pathname: '/one', |
| timestamp: '2021-01-01 05:30:00' |
| }, |
| { |
| user_id: 2, |
| name: 'engagement', |
| pathname: '/one', |
| scroll_depth: 90, |
| engagement_time: 20 * 60 * 1000, |
| timestamp: '2021-01-01 05:50:00' |
| }, |
| { |
| user_id: 2, |
| name: 'pageview', |
| pathname: '/two', |
| timestamp: '2021-01-01 05:50:00' |
| }, |
| { |
| user_id: 3, |
| pathname: '/two', |
| name: 'pageview', |
| timestamp: '2021-01-01 00:00:00' |
| } |
| ] |
| }) |
|
|
| await page.goto( |
| '/' + domain + '?period=day&date=2021-01-01&f=is,page,/one', |
| { waitUntil: 'commit' } |
| ) |
|
|
| const graphLine = page.locator(MAIN_LINE) |
| await expect(graphLine).toBeVisible() |
|
|
| const metricCases: MetricCase[] = [ |
| { |
| selector: '#visitors', |
| expectedMetricLabel: 'UNIQUE VISITORS', |
| expectedBuckets: [ |
| [0, '00:00', '1'], |
| [5, '05:00', '1'], |
| [10, '10:00', '0'] |
| ] |
| }, |
| { |
| selector: '#visits', |
| expectedMetricLabel: 'TOTAL VISITS', |
| expectedBuckets: [ |
| [0, '00:00', '1'], |
| [5, '05:00', '1'], |
| [10, '10:00', '0'] |
| ] |
| }, |
| { |
| selector: '#pageviews', |
| expectedMetricLabel: 'TOTAL PAGEVIEWS', |
| expectedBuckets: [ |
| [0, '00:00', '1'], |
| [5, '05:00', '1'], |
| [10, '10:00', '0'] |
| ] |
| }, |
| { |
| selector: '#bounce_rate', |
| expectedMetricLabel: 'BOUNCE RATE', |
| expectedBuckets: [ |
| [0, '00:00', '100%'], |
| [5, '05:00', '0%'], |
| [10, '10:00', '0%'] |
| ] |
| }, |
| { |
| selector: '#scroll_depth', |
| expectedMetricLabel: 'SCROLL DEPTH', |
| expectedBuckets: [ |
| [0, '00:00', '-'], |
| [5, '05:00', '90%'], |
| [10, '10:00', '-'] |
| ] |
| }, |
| { |
| selector: '#time_on_page', |
| expectedMetricLabel: 'TIME ON PAGE', |
| expectedBuckets: [ |
| [0, '00:00', '-'], |
| [5, '05:00', '20m 00s'], |
| [10, '10:00', '-'] |
| ] |
| } |
| ] |
|
|
| for (const { |
| selector, |
| expectedMetricLabel, |
| expectedBuckets |
| } of metricCases) { |
| await test.step(expectedMetricLabel, async () => { |
| await page.locator(selector).click() |
| await expect( |
| graphLine, |
| `Graph not visible after clicking ${selector}` |
| ).toBeVisible() |
|
|
| for (const [bucketIndex, timeLabel, metricValue] of expectedBuckets) { |
| const tooltipInfo = await hoverAndReadTooltip(page, bucketIndex) |
| expect(tooltipInfo.metricLabel).toBe(expectedMetricLabel) |
| expect( |
| tooltipInfo.mainTimeLabel, |
| `Wrong time label for ${expectedMetricLabel}` |
| ).toBe(timeLabel) |
| expect( |
| tooltipInfo.mainValue, |
| `Wrong metric value for ${expectedMetricLabel} in ${timeLabel}` |
| ).toBe(metricValue) |
| } |
| }) |
| } |
| }) |
| }) |
|
|