| import { test, expect } from '@playwright/test' |
| import { setupSite, populateStats, addCustomGoal } from '../fixtures' |
| import { |
| tabButton, |
| expectHeaders, |
| expectRows, |
| rowLink, |
| expectMetricValues, |
| dropdown, |
| modal, |
| detailsLink, |
| closeModalButton, |
| header, |
| searchInput |
| } from '../test-utils' |
|
|
| test('sources breakdown', async ({ page, request }) => { |
| const { domain } = await setupSite({ page, request }) |
|
|
| await populateStats({ |
| request, |
| domain, |
| events: [ |
| { |
| name: 'pageview', |
| referrer_source: 'DuckDuckGo', |
|
|
| referrer: 'https://duckduckgo.com/a1', |
| utm_medium: 'paid' |
| }, |
| { |
| name: 'pageview', |
| referrer_source: 'DuckDuckGo', |
| referrer: 'https://duckduckgo.com/a2', |
| click_id_param: 'gclid' |
| }, |
| { name: 'pageview', referrer_source: 'Facebook', utm_source: 'fb' }, |
| { name: 'pageview', referrer_source: 'theguardian.com' }, |
| { name: 'pageview', referrer_source: 'ablog.example.com' }, |
| { |
| name: 'pageview', |
| referrer_source: 'Google', |
| utm_medium: 'SomeUTMMedium', |
| utm_source: 'SomeUTMSource', |
| utm_campaign: 'SomeUTMCampaign', |
| utm_content: 'SomeUTMContent', |
| utm_term: 'SomeUTMTerm' |
| } |
| ] |
| }) |
|
|
| await page.goto('/' + domain, { waitUntil: 'commit' }) |
|
|
| const report = page.getByTestId('report-sources') |
|
|
| await test.step('sources tab', async () => { |
| const sourcesTabButton = tabButton(report, 'Sources') |
| await report.getByTestId('report-end').scrollIntoViewIfNeeded() |
| await expect(sourcesTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Source', 'Visitors']) |
|
|
| await expectRows(report, [ |
| 'DuckDuckGo', |
| 'Facebook', |
| 'Google', |
| 'ablog.example.com', |
| 'theguardian.com' |
| ]) |
|
|
| await expectMetricValues(report, 'DuckDuckGo', ['2', '33.3%']) |
| await expectMetricValues(report, 'Facebook', ['1', '16.7%']) |
| await expectMetricValues(report, 'Google', ['1', '16.7%']) |
| await expectMetricValues(report, 'ablog.example.com', ['1', '16.7%']) |
| await expectMetricValues(report, 'theguardian.com', ['1', '16.7%']) |
| }) |
|
|
| await test.step('sources modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Sources' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Source', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), [ |
| 'DuckDuckGo', |
| 'Facebook', |
| 'Google', |
| 'ablog.example.com', |
| 'theguardian.com' |
| ]) |
|
|
| await expectMetricValues(modal(page), 'DuckDuckGo', ['2', '100%', '0s']) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('clicking sources entry shows referrers', async () => { |
| await rowLink(report, 'DuckDuckGo').click() |
| await expect(page).toHaveURL(/f=is,source,DuckDuckGo/) |
|
|
| await expect(tabButton(report, 'Top referrers')).toHaveAttribute( |
| 'data-active', |
| 'true' |
| ) |
|
|
| |
| await tabButton(report, 'Top referrers').hover() |
|
|
| await expectHeaders(report, ['Referrer', 'Visitors']) |
|
|
| await expectRows(report, [ |
| 'https://duckduckgo.com/a1', |
| 'https://duckduckgo.com/a2' |
| ]) |
| }) |
|
|
| await test.step('referrers modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Referrer drilldown' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Referrer', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), [ |
| 'https://duckduckgo.com/a1', |
| 'https://duckduckgo.com/a2' |
| ]) |
|
|
| await closeModalButton(page).click() |
|
|
| await page |
| .getByRole('button', { name: 'Remove filter: Source is DuckDuckGo' }) |
| .click() |
| }) |
|
|
| |
| await test.step('clicking Google source entry opens search terms', async () => { |
| await rowLink(report, 'Google').click() |
| await expect(page).toHaveURL(/f=is,source,Google/) |
|
|
| await expect(tabButton(report, 'Search terms')).toHaveAttribute( |
| 'data-active', |
| 'true' |
| ) |
|
|
| |
| await tabButton(report, 'Search terms').hover() |
|
|
| await expectHeaders(report, ['Search term', 'Visitors']) |
|
|
| await expectMetricValues(report, 'simple web analytics', ['25']) |
| await expectMetricValues(report, 'open-source analytics', ['15']) |
| }) |
|
|
| await test.step('search-terms modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Google search terms' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Search term', |
| 'Visitors', |
| 'Impressions', |
| 'CTR', |
| 'Position' |
| ]) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await page |
| .getByRole('button', { name: 'Remove filter: Source is Google' }) |
| .click() |
|
|
| await test.step('channels tab', async () => { |
| const channelsTabButton = tabButton(report, 'Channels') |
| await channelsTabButton.click() |
| await expect(channelsTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Channel', 'Visitors']) |
|
|
| await expectRows(report, [ |
| 'Organic Search', |
| 'Referral', |
| 'Organic Social', |
| 'Paid Search' |
| ]) |
|
|
| await expectMetricValues(report, 'Organic Search', ['2', '33.3%']) |
| await expectMetricValues(report, 'Referral', ['2', '33.3%']) |
| await expectMetricValues(report, 'Organic Social', ['1', '16.7%']) |
| await expectMetricValues(report, 'Paid Search', ['1', '16.7%']) |
| }) |
|
|
| await test.step('channels modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Acquisition channels' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Channel', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), [ |
| 'Organic Search', |
| 'Referral', |
| 'Organic Social', |
| 'Paid Search' |
| ]) |
|
|
| await expectMetricValues(modal(page), 'Referral', ['2', '100%', '0s']) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('campaigns > UTM mediums tab', async () => { |
| await tabButton(report, 'Campaigns').click() |
| await dropdown(report).getByRole('button', { name: 'UTM mediums' }).click() |
|
|
| await expect(tabButton(report, 'UTM mediums')).toHaveAttribute( |
| 'data-active', |
| 'true' |
| ) |
|
|
| await expectHeaders(report, ['UTM medium', 'Visitors']) |
|
|
| await expectRows(report, ['SomeUTMMedium', 'paid']) |
|
|
| await expectMetricValues(report, 'SomeUTMMedium', ['1', '50%']) |
| await expectMetricValues(report, 'paid', ['1', '50%']) |
| }) |
|
|
| await test.step('UTM mediums modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'UTM mediums' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'UTM medium', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), ['SomeUTMMedium', 'paid']) |
|
|
| await expectMetricValues(modal(page), 'SomeUTMMedium', ['1', '100%', '0s']) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('campaigns > UTM sources tab', async () => { |
| await tabButton(report, 'UTM mediums').click() |
| await dropdown(report).getByRole('button', { name: 'UTM sources' }).click() |
|
|
| await expect(tabButton(report, 'UTM sources')).toHaveAttribute( |
| 'data-active', |
| 'true' |
| ) |
|
|
| await expectHeaders(report, ['UTM source', 'Visitors']) |
|
|
| await expectRows(report, ['SomeUTMSource', 'fb']) |
|
|
| await expectMetricValues(report, 'SomeUTMSource', ['1', '50%']) |
| await expectMetricValues(report, 'fb', ['1', '50%']) |
| }) |
|
|
| await test.step('UTM sources modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'UTM sources' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'UTM source', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), ['SomeUTMSource', 'fb']) |
|
|
| await expectMetricValues(modal(page), 'SomeUTMSource', ['1', '100%', '0s']) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('campaigns > UTM campaigns tab', async () => { |
| await tabButton(report, 'UTM sources').click() |
| await dropdown(report) |
| .getByRole('button', { name: 'UTM campaigns' }) |
| .click() |
|
|
| await expect(tabButton(report, 'UTM campaigns')).toHaveAttribute( |
| 'data-active', |
| 'true' |
| ) |
|
|
| await expectHeaders(report, ['UTM campaign', 'Visitors']) |
|
|
| await expectRows(report, ['SomeUTMCampaign']) |
|
|
| await expectMetricValues(report, 'SomeUTMCampaign', ['1', '100%']) |
| }) |
|
|
| await test.step('UTM campaigns modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'UTM campaigns' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'UTM campaign', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), ['SomeUTMCampaign']) |
|
|
| await expectMetricValues(modal(page), 'SomeUTMCampaign', [ |
| '1', |
| '100%', |
| '0s' |
| ]) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('campaigns > UTM contents tab', async () => { |
| await tabButton(report, 'UTM campaigns').click() |
| await dropdown(report).getByRole('button', { name: 'UTM contents' }).click() |
|
|
| await expect(tabButton(report, 'UTM contents')).toHaveAttribute( |
| 'data-active', |
| 'true' |
| ) |
|
|
| await expectHeaders(report, ['UTM content', 'Visitors']) |
|
|
| await expectRows(report, ['SomeUTMContent']) |
|
|
| await expectMetricValues(report, 'SomeUTMContent', ['1', '100%']) |
| }) |
|
|
| await test.step('UTM contents modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'UTM contents' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'UTM content', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), ['SomeUTMContent']) |
|
|
| await expectMetricValues(modal(page), 'SomeUTMContent', ['1', '100%', '0s']) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('campaigns > UTM terms tab', async () => { |
| await tabButton(report, 'UTM contents').click() |
| await dropdown(report).getByRole('button', { name: 'UTM terms' }).click() |
|
|
| await expect(tabButton(report, 'UTM terms')).toHaveAttribute( |
| 'data-active', |
| 'true' |
| ) |
|
|
| await expectHeaders(report, ['UTM term', 'Visitors']) |
|
|
| await expectRows(report, ['SomeUTMTerm']) |
|
|
| await expectMetricValues(report, 'SomeUTMTerm', ['1', '100%']) |
| }) |
|
|
| await test.step('UTM terms modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'UTM terms' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'UTM term', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), ['SomeUTMTerm']) |
|
|
| await expectMetricValues(modal(page), 'SomeUTMTerm', ['1', '100%', '0s']) |
|
|
| await closeModalButton(page).click() |
| }) |
| }) |
|
|
| |
| test('sources breakdown - search terms failure modes', async ({ |
| page, |
| request |
| }) => { |
| const { domain } = await setupSite({ page, request }) |
|
|
| await populateStats({ |
| request, |
| domain, |
| events: [ |
| { name: 'pageview', referrer_source: 'Google', pathname: '/empty' }, |
| { |
| name: 'pageview', |
| referrer_source: 'Google', |
| pathname: '/unsupported-filters' |
| }, |
| { |
| name: 'pageview', |
| referrer_source: 'Google', |
| pathname: '/not-configured' |
| } |
| ] |
| }) |
|
|
| const report = page.getByTestId('report-sources') |
| const searchTermsTabButton = tabButton(report, 'Search terms') |
|
|
| await test.step('empty', async () => { |
| await page.goto('/' + domain + '?f=is,source,Google&f=is,page,%2Fempty', { |
| waitUntil: 'commit' |
| }) |
|
|
| await report.getByTestId('report-end').scrollIntoViewIfNeeded() |
| await expect(searchTermsTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expect(report.getByText('No data yet')).toBeVisible() |
| }) |
|
|
| await test.step('unsupported filters', async () => { |
| await page.goto( |
| '/' + domain + '?f=is,source,Google&f=is,page,%2Funsupported-filters', |
| { |
| waitUntil: 'commit' |
| } |
| ) |
|
|
| await report.getByTestId('report-end').scrollIntoViewIfNeeded() |
| await expect(searchTermsTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expect( |
| report.getByText('Unable to fetch keyword data from Search Console') |
| ).toBeVisible() |
|
|
| await expect( |
| report.getByText('does not support the current set of filters') |
| ).toBeVisible() |
| }) |
|
|
| await test.step('not configured', async () => { |
| await page.goto( |
| '/' + domain + '?f=is,source,Google&f=is,page,%2Fnot-configured', |
| { |
| waitUntil: 'commit' |
| } |
| ) |
|
|
| await report.getByTestId('report-end').scrollIntoViewIfNeeded() |
| await expect(searchTermsTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expect( |
| report.getByText('The site is not connected to Google Search Keywords') |
| ).toBeVisible() |
| }) |
| }) |
|
|
| test('pages breakdown', async ({ page, request }) => { |
| const { domain } = await setupSite({ page, request }) |
|
|
| await populateStats({ |
| request, |
| domain, |
| events: [ |
| { user_id: 123, name: 'pageview', pathname: '/page1' }, |
| { user_id: 123, name: 'pageview', pathname: '/page2' }, |
| { user_id: 123, name: 'pageview', pathname: '/page3' }, |
| { user_id: 124, name: 'pageview', pathname: '/page1' }, |
| { user_id: 124, name: 'pageview', pathname: '/page2' }, |
| { name: 'pageview', pathname: '/page1' }, |
| { name: 'pageview', pathname: '/other' } |
| ] |
| }) |
|
|
| await page.goto('/' + domain, { waitUntil: 'commit' }) |
|
|
| const report = page.getByTestId('report-pages') |
|
|
| await test.step('top pages tab', async () => { |
| const pagesTabButton = tabButton(report, 'Top pages') |
| await report.getByTestId('report-end').scrollIntoViewIfNeeded() |
| await expect(pagesTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Page', 'Visitors']) |
|
|
| await expectRows(report, ['/page1', '/page2', '/other', '/page3']) |
|
|
| await expectMetricValues(report, '/page1', ['3', '75%']) |
| await expectMetricValues(report, '/page2', ['2', '50%']) |
| await expectMetricValues(report, '/other', ['1', '25%']) |
| await expectMetricValues(report, '/page3', ['1', '25%']) |
| }) |
|
|
| await test.step('entry pages tab', async () => { |
| const entryPagesTabButton = tabButton(report, 'Entry pages') |
| entryPagesTabButton.click() |
| await expect(entryPagesTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Entry page', 'Unique entrances']) |
|
|
| await expectRows(report, ['/page1', '/other']) |
|
|
| await expectMetricValues(report, '/page1', ['3', '75%']) |
| await expectMetricValues(report, '/other', ['1', '25%']) |
| }) |
|
|
| await test.step('Entry pages modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Entry pages' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Entry page', |
| /Unique entrances/, |
| /Total entrances/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), ['/page1', '/other']) |
|
|
| await expectMetricValues(modal(page), '/page1', ['3', '3', '33%', '0s']) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('exit pages tab', async () => { |
| const exitPagesTabButton = tabButton(report, 'Exit pages') |
| exitPagesTabButton.click() |
| await expect(exitPagesTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Exit page', 'Unique exits']) |
|
|
| await expectRows(report, ['/other', '/page1', '/page2', '/page3']) |
|
|
| await expectMetricValues(report, '/other', ['1', '25%']) |
| await expectMetricValues(report, '/page1', ['1', '25%']) |
| await expectMetricValues(report, '/page2', ['1', '25%']) |
| await expectMetricValues(report, '/page3', ['1', '25%']) |
| }) |
|
|
| await test.step('Exit pages modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Exit pages' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Exit page', |
| /Unique exits/, |
| /Total exits/, |
| /Exit rate/ |
| ]) |
|
|
| await expectRows(modal(page), ['/other', '/page1', '/page2', '/page3']) |
|
|
| await expectMetricValues(modal(page), '/other', ['1', '1', '100%']) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('exit pages modal with an event filter applied', async () => { |
| await page.goto('/' + domain + '?f=is,page,/page1', { waitUntil: 'commit' }) |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Exit pages' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Exit page', |
| /Unique exits/, |
| /Total exits/ |
| ]) |
|
|
| await expectRows(modal(page), ['/page1', '/page2', '/page3']) |
|
|
| await expectMetricValues(modal(page), '/page1', ['1', '1']) |
| await expectMetricValues(modal(page), '/page2', ['1', '1']) |
| await expectMetricValues(modal(page), '/page3', ['1', '1']) |
|
|
| await closeModalButton(page).click() |
| }) |
| }) |
|
|
| test('pages breakdown modal', async ({ page, request }) => { |
| const { domain } = await setupSite({ page, request }) |
|
|
| const pagesCount = 110 |
|
|
| |
| const pageEvents = Array(pagesCount) |
| .fill(null) |
| .map((_, idx) => { |
| return Array(idx + 1) |
| .fill(null) |
| .map(() => { |
| return { name: 'pageview', pathname: `/page${idx + 1}/foo` } |
| }) |
| }) |
| .flat() |
|
|
| await populateStats({ |
| request, |
| domain, |
| events: pageEvents |
| }) |
|
|
| await page.goto('/' + domain, { waitUntil: 'commit' }) |
|
|
| const report = page.getByTestId('report-pages') |
|
|
| const pagesTabButton = tabButton(report, 'Top pages') |
| await report.getByTestId('report-end').scrollIntoViewIfNeeded() |
| await expect(pagesTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Top pages' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Page', |
| /Visitors/, |
| /Pageviews/, |
| /Bounce rate/, |
| /Time on page/, |
| /Scroll depth/ |
| ]) |
|
|
| await test.step('displays 100 entries on a single page', async () => { |
| const pageRows = Array(100) |
| .fill(null) |
| .map((_, idx) => { |
| return `/page${pagesCount - idx}/foo` |
| }) |
|
|
| await expectRows(modal(page), pageRows) |
|
|
| await expectMetricValues(modal(page), '/page110/foo', [ |
| '110', |
| '110', |
| '100%', |
| '-', |
| '-' |
| ]) |
|
|
| await expectMetricValues(modal(page), '/page11/foo', [ |
| '11', |
| '11', |
| '100%', |
| '-', |
| '-' |
| ]) |
| }) |
|
|
| await test.step('loads more when requested', async () => { |
| const loadMoreButton = modal(page).getByRole('button', { |
| name: 'Load more' |
| }) |
|
|
| await loadMoreButton.scrollIntoViewIfNeeded() |
| await loadMoreButton.click() |
|
|
| await expectMetricValues(modal(page), '/page10/foo', [ |
| '10', |
| '10', |
| '100%', |
| '-', |
| '-' |
| ]) |
|
|
| await expectMetricValues(modal(page), '/page1/foo', [ |
| '1', |
| '1', |
| '100%', |
| '-', |
| '-' |
| ]) |
| }) |
|
|
| await test.step('sorts when clicking on column header', async () => { |
| await header(modal(page), 'Visitors').click() |
|
|
| const pageRows = Array(100) |
| .fill(null) |
| .map((_, idx) => { |
| return `/page${idx + 1}/foo` |
| }) |
|
|
| await expectRows(modal(page), pageRows) |
| }) |
|
|
| await test.step('filters when using search', async () => { |
| await searchInput(modal(page)).fill('page9') |
|
|
| await expectRows(modal(page), [ |
| '/page9/foo', |
| '/page90/foo', |
| '/page91/foo', |
| '/page92/foo', |
| '/page93/foo', |
| '/page94/foo', |
| '/page95/foo', |
| '/page96/foo', |
| '/page97/foo', |
| '/page98/foo', |
| '/page99/foo' |
| ]) |
| }) |
|
|
| await test.step('close button closes the modal', async () => { |
| await closeModalButton(page).click() |
|
|
| await expect(modal(page)).toBeHidden() |
| }) |
|
|
| await test.step('reopening the modal resets the search state but preserves', async () => { |
| await detailsLink(report).click() |
|
|
| await expect(modal(page)).toContainClass('is-open') |
|
|
| await expect(searchInput(modal(page))).toHaveValue('') |
|
|
| const pageRows = Array(100) |
| .fill(null) |
| .map((_, idx) => { |
| return `/page${idx + 1}/foo` |
| }) |
|
|
| await expectRows(modal(page), pageRows) |
| }) |
| }) |
|
|
| test('pages breakdown with a pageview goal filter applied', async ({ |
| page, |
| request |
| }) => { |
| const { domain } = await setupSite({ page, request }) |
|
|
| await populateStats({ |
| request, |
| domain, |
| events: [ |
| { user_id: 123, name: 'pageview', pathname: '/page1' }, |
| { user_id: 123, name: 'pageview', pathname: '/page2' }, |
| { user_id: 123, name: 'pageview', pathname: '/page3' }, |
| { |
| user_id: 123, |
| name: 'purchase', |
| revenue_reporting_amount: '23', |
| revenue_reporting_currency: 'EUR' |
| }, |
| { user_id: 124, name: 'pageview', pathname: '/page1' }, |
| { user_id: 124, name: 'pageview', pathname: '/page2' }, |
| { user_id: 124, name: 'create_site' }, |
| { name: 'pageview', pathname: '/page1' }, |
| { name: 'pageview', pathname: '/other' } |
| ] |
| }) |
|
|
| await addCustomGoal({ page, domain, name: 'create_site' }) |
| await addCustomGoal({ page, domain, name: 'purchase', currency: 'EUR' }) |
|
|
| const report = page.getByTestId('report-pages') |
|
|
| await test.step('custom goal filter applied', async () => { |
| await page.goto('/' + domain + '?f=is,goal,create_site', { |
| waitUntil: 'commit' |
| }) |
|
|
| const pagesTabButton = tabButton(report, 'Conversion pages') |
| await report.getByTestId('report-end').scrollIntoViewIfNeeded() |
| await expect(pagesTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Page', 'Conversions', 'CR']) |
|
|
| await expectRows(report, ['/']) |
|
|
| await expectMetricValues(report, '/', ['1', '50%']) |
| }) |
|
|
| await test.step('details modal after custom goal filter applied', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Conversion pages' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Page', |
| /Total visitors/, |
| /Conversions/, |
| /CR/ |
| ]) |
|
|
| await expectRows(modal(page), ['/']) |
|
|
| await expectMetricValues(modal(page), '/', ['2', '1', '50%']) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('revenue goal filter applied', async () => { |
| await page.goto('/' + domain + '?f=is,goal,purchase', { |
| waitUntil: 'commit' |
| }) |
|
|
| const pagesTabButton = tabButton(report, 'Conversion pages') |
| await report.getByTestId('report-end').scrollIntoViewIfNeeded() |
| await expect(pagesTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Page', 'Conversions', 'CR']) |
|
|
| await expectRows(report, ['/']) |
|
|
| await expectMetricValues(report, '/', ['1', '50%']) |
| }) |
|
|
| await test.step('details modal after revenue goal filter applied', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Conversion pages' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Page', |
| /Total visitors/, |
| /Conversions/, |
| /CR/, |
| /Revenue/, |
| /Average/ |
| ]) |
|
|
| await expectRows(modal(page), ['/']) |
|
|
| await expectMetricValues(modal(page), '/', [ |
| '2', |
| '1', |
| '50%', |
| '€23.0', |
| '€23.0' |
| ]) |
|
|
| await closeModalButton(page).click() |
| }) |
| }) |
|
|
| test('pages breakdown - URL mode', async ({ page, request }) => { |
| const { domain } = await setupSite({ page, request }) |
|
|
| await populateStats({ |
| request, |
| domain, |
| events: [ |
| { |
| user_id: 1, |
| name: 'pageview', |
| hostname: 'blog.example.com', |
| pathname: '/post' |
| }, |
| { |
| user_id: 1, |
| name: 'pageview', |
| hostname: 'blog.example.com', |
| pathname: '/post' |
| }, |
| { |
| user_id: 2, |
| name: 'pageview', |
| hostname: 'blog.example.com', |
| pathname: '/post' |
| }, |
| { |
| user_id: 3, |
| name: 'pageview', |
| hostname: 'docs.example.com', |
| pathname: '/api' |
| } |
| ] |
| }) |
|
|
| await page.goto('/' + domain, { waitUntil: 'commit' }) |
| const report = page.getByTestId('report-pages') |
|
|
| await test.step('switch to URL mode', async () => { |
| await report.getByRole('button', { name: 'Breakdown options' }).click() |
| await page.getByRole('button', { name: 'URL' }).click() |
| }) |
|
|
| await test.step('top pages in URL mode', async () => { |
| await expect(tabButton(report, 'Top pages')).toHaveAttribute( |
| 'data-active', |
| 'true' |
| ) |
|
|
| await expectHeaders(report, ['URL', 'Visitors']) |
| await expectRows(report, ['blog.example.com/post', 'docs.example.com/api']) |
| await expectMetricValues(report, 'blog.example.com/post', ['2', '66.7%']) |
| await expectMetricValues(report, 'docs.example.com/api', ['1', '33.3%']) |
| }) |
|
|
| await test.step('clicking a URL mode row applies hostname and page filters', async () => { |
| await rowLink(report, 'blog.example.com/post').click() |
|
|
| await expect( |
| page.getByRole('button', { |
| name: 'Remove filter: Hostname is blog.example.com' |
| }) |
| ).toBeVisible() |
| await expect( |
| page.getByRole('button', { name: 'Remove filter: Page is /post' }) |
| ).toBeVisible() |
|
|
| await page |
| .getByRole('button', { |
| name: 'Remove filter: Hostname is blog.example.com' |
| }) |
| .click() |
| await page |
| .getByRole('button', { name: 'Remove filter: Page is /post' }) |
| .click() |
| }) |
|
|
| await test.step('entry pages in URL mode', async () => { |
| await tabButton(report, 'Entry pages').click() |
|
|
| await expectHeaders(report, ['URL', 'Unique entrances']) |
| await expectRows(report, ['blog.example.com/post', 'docs.example.com/api']) |
| await expectMetricValues(report, 'blog.example.com/post', ['2', '66.7%']) |
| await expectMetricValues(report, 'docs.example.com/api', ['1', '33.3%']) |
| }) |
|
|
| await test.step('entry pages modal in URL mode', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Entry pages' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'URL', |
| /Unique entrances/, |
| /Total entrances/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), [ |
| 'blog.example.com/post', |
| 'docs.example.com/api' |
| ]) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('exit pages in URL mode', async () => { |
| await tabButton(report, 'Exit pages').click() |
|
|
| await expectHeaders(report, ['URL', 'Unique exits']) |
| await expectRows(report, ['blog.example.com/post', 'docs.example.com/api']) |
| }) |
|
|
| await test.step('exit pages modal in URL mode', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Exit pages' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'URL', |
| /Unique exits/, |
| /Total exits/, |
| /Exit rate/ |
| ]) |
|
|
| await expectRows(modal(page), [ |
| 'blog.example.com/post', |
| 'docs.example.com/api' |
| ]) |
|
|
| await closeModalButton(page).click() |
| }) |
| }) |
|
|
| test('locations breakdown', async ({ page, request }) => { |
| const { domain } = await setupSite({ page, request }) |
|
|
| await populateStats({ |
| request, |
| domain, |
| events: [ |
| { |
| name: 'pageview', |
| country_code: 'EE', |
| subdivision1_code: 'EE-37', |
| city_geoname_id: 588_409 |
| }, |
| { |
| name: 'pageview', |
| country_code: 'EE', |
| subdivision1_code: 'EE-79', |
| city_geoname_id: 588_335 |
| }, |
| { |
| name: 'pageview', |
| country_code: 'PL', |
| subdivision1_code: 'PL-14', |
| city_geoname_id: 756_135 |
| }, |
| { |
| name: 'pageview', |
| country_code: '' |
| } |
| ] |
| }) |
|
|
| await page.goto('/' + domain, { waitUntil: 'commit' }) |
|
|
| const report = page.getByTestId('report-locations') |
|
|
| await test.step('map tab', async () => { |
| const mapTabButton = tabButton(report, 'Map') |
| await report.getByTestId('report-end').scrollIntoViewIfNeeded() |
| await expect(mapTabButton).toHaveAttribute('data-active', 'true') |
|
|
| |
| await expect(report.locator('svg path.country').first()).toBeVisible() |
| }) |
|
|
| await test.step('countries tab', async () => { |
| const countriesTabButton = tabButton(report, 'Countries') |
| await countriesTabButton.click() |
| await expect(countriesTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Country', 'Visitors']) |
|
|
| await expectRows(report, [/Estonia/, /Poland/]) |
|
|
| await expectMetricValues(report, 'Estonia', ['2', '66.7%']) |
| await expectMetricValues(report, 'Poland', ['1', '33.3%']) |
| }) |
|
|
| await test.step('countries modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Countries' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Country', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), [/Estonia/, /Poland/]) |
|
|
| await expectMetricValues(modal(page), 'Estonia', ['2', '100%', '0s']) |
|
|
| await expect(searchInput(modal(page))).toBeVisible() |
|
|
| await searchInput(modal(page)).fill('Esto') |
| await expectRows(modal(page), [/Estonia/]) |
|
|
| await searchInput(modal(page)).fill('') |
| await expectRows(modal(page), [/Estonia/, /Poland/]) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| const regionsTabButton = tabButton(report, 'Regions') |
|
|
| await test.step('clicking country entry shows regions', async () => { |
| await rowLink(report, 'Estonia').click() |
| await expect(page).toHaveURL(/f=is,country,EE/) |
|
|
| await expect(regionsTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await page |
| .getByRole('button', { name: 'Remove filter: Country is Estonia' }) |
| .click() |
| }) |
|
|
| await test.step('regions tab', async () => { |
| await regionsTabButton.click() |
| await expect(regionsTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Region', 'Visitors']) |
|
|
| await expectRows(report, [/Harjumaa/, /Mazovia/, /Tartumaa/]) |
|
|
| await expectMetricValues(report, 'Harjumaa', ['1', '33.3%']) |
| await expectMetricValues(report, 'Tartumaa', ['1', '33.3%']) |
| await expectMetricValues(report, 'Mazovia', ['1', '33.3%']) |
| }) |
|
|
| await test.step('regions modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Regions' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Region', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), [/Harjumaa/, /Mazovia/, /Tartumaa/]) |
|
|
| await expectMetricValues(modal(page), 'Harjumaa', ['1', '100%', '0s']) |
|
|
| await expect(searchInput(modal(page))).toBeVisible() |
|
|
| await searchInput(modal(page)).fill('Harju') |
| await expectRows(modal(page), [/Harjumaa/]) |
|
|
| await searchInput(modal(page)).fill('') |
| await expectRows(modal(page), [/Harjumaa/, /Mazovia/, /Tartumaa/]) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| const citiesTabButton = tabButton(report, 'Cities') |
|
|
| await test.step('clicking region entry shows cities', async () => { |
| await rowLink(report, 'Harjumaa').click() |
| await expect(page).toHaveURL(/f=is,region,EE-37/) |
|
|
| await expect(citiesTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await page |
| .getByRole('button', { name: 'Remove filter: Region is Harjumaa' }) |
| .click() |
| }) |
|
|
| await test.step('cities tab', async () => { |
| await citiesTabButton.click() |
| await expect(citiesTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['City', 'Visitors']) |
|
|
| await expectRows(report, [/Tallinn/, /Tartu/, /Warsaw/]) |
|
|
| await expectMetricValues(report, 'Tartu', ['1', '33.3%']) |
| await expectMetricValues(report, 'Tallinn', ['1', '33.3%']) |
| await expectMetricValues(report, 'Warsaw', ['1', '33.3%']) |
| }) |
|
|
| await test.step('cities modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Cities' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'City', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), [/Tallinn/, /Tartu/, /Warsaw/]) |
|
|
| await expectMetricValues(modal(page), 'Tartu', ['1', '100%', '0s']) |
|
|
| await expect(searchInput(modal(page))).toBeVisible() |
|
|
| await searchInput(modal(page)).fill('Tallinn') |
| await expectRows(modal(page), [/Tallinn/]) |
|
|
| await searchInput(modal(page)).fill('') |
| await expectRows(modal(page), [/Tallinn/, /Tartu/, /Warsaw/]) |
|
|
| await closeModalButton(page).click() |
| }) |
| }) |
|
|
| test('locations breakdown with a revenue goal filter applied', async ({ |
| page, |
| request |
| }) => { |
| const { domain } = await setupSite({ page, request }) |
|
|
| await populateStats({ |
| request, |
| domain, |
| events: [ |
| { |
| user_id: 1, |
| name: 'pageview', |
| country_code: 'A1' |
| }, |
| { |
| user_id: 2, |
| name: 'pageview', |
| country_code: 'A1' |
| }, |
| { |
| user_id: 2, |
| name: 'purchase', |
| revenue_reporting_amount: '23', |
| revenue_reporting_currency: 'EUR', |
| country_code: 'A1' |
| }, |
| { |
| user_id: 3, |
| name: 'pageview', |
| country_code: 'PL', |
| subdivision1_code: 'PL-14', |
| city_geoname_id: 756_135 |
| }, |
| { |
| user_id: 4, |
| name: 'pageview', |
| country_code: 'EE', |
| subdivision1_code: 'EE-37', |
| city_geoname_id: 588_409 |
| }, |
| { |
| user_id: 4, |
| name: 'purchase', |
| revenue_reporting_amount: '12345.67', |
| revenue_reporting_currency: 'EUR', |
| country_code: 'EE', |
| subdivision1_code: 'EE-37', |
| city_geoname_id: 588_409 |
| } |
| ] |
| }) |
|
|
| await addCustomGoal({ page, domain, name: 'purchase', currency: 'EUR' }) |
|
|
| await page.goto('/' + domain + '?f=is,goal,purchase', { |
| waitUntil: 'commit' |
| }) |
|
|
| const report = page.getByTestId('report-locations') |
|
|
| await test.step('countries report shows conversions for revenue goal', async () => { |
| await tabButton(report, 'Countries').click() |
| await report.getByTestId('report-end').scrollIntoViewIfNeeded() |
|
|
| await expectHeaders(report, ['Country', 'Conversions', 'CR']) |
|
|
| await expectRows(report, [/Anonymous VPN Service/, /Estonia/]) |
|
|
| await expectMetricValues(report, 'Anonymous VPN Service', ['1', '50%']) |
| await expectMetricValues(report, 'Estonia', ['1', '100%']) |
| }) |
|
|
| await test.step('countries details modal includes revenue columns', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Countries' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Country', |
| /Total visitors/, |
| /Conversions/, |
| /CR/, |
| /Revenue/, |
| /Average/ |
| ]) |
|
|
| await expectRows(modal(page), [/Anonymous VPN Service/, /Estonia/]) |
|
|
| await expectMetricValues(modal(page), 'Anonymous VPN Service', [ |
| '2', |
| '1', |
| '50%', |
| '€23.0', |
| '€23.0' |
| ]) |
| await expectMetricValues(modal(page), 'Estonia', [ |
| '1', |
| '1', |
| '100%', |
| '€12.3K', |
| '€12.3K' |
| ]) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('regions report shows conversions for revenue goal', async () => { |
| await tabButton(report, 'Regions').click() |
|
|
| await expectHeaders(report, ['Region', 'Conversions', 'CR']) |
|
|
| await expectRows(report, [/Harjumaa/]) |
|
|
| await expectMetricValues(report, 'Harjumaa', ['1', '100%']) |
| }) |
|
|
| await test.step('regions details modal includes revenue columns', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Regions' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Region', |
| /Total visitors/, |
| /Conversions/, |
| /CR/, |
| /Revenue/, |
| /Average/ |
| ]) |
|
|
| await expectRows(modal(page), [/Harjumaa/]) |
|
|
| await expectMetricValues(modal(page), 'Harjumaa', [ |
| '1', |
| '1', |
| '100%', |
| '€12.3K', |
| '€12.3K' |
| ]) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('cities report shows conversions for revenue goal', async () => { |
| await tabButton(report, 'Cities').click() |
|
|
| await expectHeaders(report, ['City', 'Conversions', 'CR']) |
|
|
| await expectRows(report, [/Tallinn/]) |
|
|
| await expectMetricValues(report, 'Tallinn', ['1', '100%']) |
| }) |
|
|
| await test.step('cities details modal includes revenue columns', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Cities' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'City', |
| /Total visitors/, |
| /Conversions/, |
| /CR/, |
| /Revenue/, |
| /Average/ |
| ]) |
|
|
| await expectRows(modal(page), [/Tallinn/]) |
|
|
| await expectMetricValues(modal(page), 'Tallinn', [ |
| '1', |
| '1', |
| '100%', |
| '€12.3K', |
| '€12.3K' |
| ]) |
|
|
| await closeModalButton(page).click() |
| }) |
| }) |
|
|
| test('devices breakdown', async ({ page, request }) => { |
| const { domain } = await setupSite({ page, request }) |
|
|
| await populateStats({ |
| request, |
| domain, |
| events: [ |
| { |
| name: 'pageview', |
| screen_size: 'Desktop', |
| browser: 'Chrome', |
| browser_version: '14.0.7', |
| operating_system: 'Windows', |
| operating_system_version: '11' |
| }, |
| { |
| name: 'pageview', |
| screen_size: 'Desktop', |
| browser: 'Firefox', |
| browser_version: '98', |
| operating_system: 'MacOS', |
| operating_system_version: '10.15' |
| }, |
| { |
| name: 'pageview', |
| screen_size: 'Mobile', |
| browser: 'Safari', |
| browser_version: '123', |
| operating_system: 'iOS', |
| operating_system_version: '16.15' |
| } |
| ] |
| }) |
|
|
| await page.goto('/' + domain, { waitUntil: 'commit' }) |
|
|
| const report = page.getByTestId('report-devices') |
|
|
| const browsersTabButton = tabButton(report, 'Browsers') |
|
|
| await test.step('browsers tab', async () => { |
| await report.getByTestId('report-end').scrollIntoViewIfNeeded() |
| await expect(browsersTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Browser', 'Visitors']) |
|
|
| await expectRows(report, ['Chrome', 'Firefox', 'Safari']) |
|
|
| await expectMetricValues(report, 'Chrome', ['1', '33.3%']) |
| await expectMetricValues(report, 'Firefox', ['1', '33.3%']) |
| await expectMetricValues(report, 'Safari', ['1', '33.3%']) |
| }) |
|
|
| await test.step('browsers modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Browsers' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Browser', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), ['Chrome', 'Firefox', 'Safari']) |
|
|
| await expectMetricValues(modal(page), 'Chrome', ['1', '100%', '0s']) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('browser versions', async () => { |
| await rowLink(report, 'Firefox').click() |
|
|
| await expect(page).toHaveURL(/f=is,browser,Firefox/) |
|
|
| await expect(browsersTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Browser version', 'Visitors']) |
|
|
| await expectRows(report, ['Firefox 98']) |
|
|
| await expectMetricValues(report, 'Firefox 98', ['1', '100%']) |
| }) |
|
|
| await test.step('browser versions modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Browser versions' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Browser version', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), ['98']) |
|
|
| await expectMetricValues(modal(page), '98', ['1', '100%', '0s']) |
|
|
| await closeModalButton(page).click() |
|
|
| await page |
| .getByRole('button', { name: 'Remove filter: Browser is Firefox' }) |
| .click() |
| }) |
|
|
| const osTabButton = tabButton(report, 'Operating systems') |
|
|
| await test.step('operating systems tab', async () => { |
| await osTabButton.click() |
| await expect(osTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Operating system', 'Visitors']) |
|
|
| await expectRows(report, ['MacOS', 'Windows', 'iOS']) |
|
|
| await expectMetricValues(report, 'MacOS', ['1', '33.3%']) |
| await expectMetricValues(report, 'Windows', ['1', '33.3%']) |
| await expectMetricValues(report, 'iOS', ['1', '33.3%']) |
| }) |
|
|
| await test.step('operating systems modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Operating systems' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Operating system', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), ['MacOS', 'Windows', 'iOS']) |
|
|
| await expectMetricValues(modal(page), 'MacOS', ['1', '100%', '0s']) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('operating system versions', async () => { |
| await rowLink(report, 'Windows').click() |
|
|
| await expect(page).toHaveURL(/f=is,os,Windows/) |
|
|
| await expect(osTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Operating system version', 'Visitors']) |
|
|
| await expectRows(report, ['Windows 11']) |
|
|
| await expectMetricValues(report, 'Windows 11', ['1', '100%']) |
| }) |
|
|
| await test.step('operating system versions modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Operating system versions' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Operating system version', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), ['11']) |
|
|
| await expectMetricValues(modal(page), '11', ['1', '100%', '0s']) |
|
|
| await closeModalButton(page).click() |
|
|
| await page |
| .getByRole('button', { |
| name: 'Remove filter: Operating system is Windows' |
| }) |
| .click() |
| }) |
|
|
| await test.step('devices tab', async () => { |
| const devicesTabButton = tabButton(report, 'Devices') |
| await devicesTabButton.click() |
| await expect(devicesTabButton).toHaveAttribute('data-active', 'true') |
|
|
| await expectHeaders(report, ['Device', 'Visitors']) |
|
|
| await expectRows(report, ['Desktop', 'Mobile']) |
|
|
| await expectMetricValues(report, 'Desktop', ['2', '66.7%']) |
| await expectMetricValues(report, 'Mobile', ['1', '33.3%']) |
| }) |
|
|
| await test.step('devices modal', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Devices' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Device', |
| /Visitors/, |
| /Bounce rate/, |
| /Visit duration/ |
| ]) |
|
|
| await expectRows(modal(page), ['Desktop', 'Mobile']) |
|
|
| await expectMetricValues(modal(page), 'Desktop', ['2', '100%', '0s']) |
|
|
| await closeModalButton(page).click() |
| }) |
| }) |
|
|
| test('devices breakdown with a revenue goal filter applied', async ({ |
| page, |
| request |
| }) => { |
| const { domain } = await setupSite({ page, request }) |
|
|
| await populateStats({ |
| request, |
| domain, |
| events: [ |
| { |
| user_id: 1, |
| name: 'pageview', |
| screen_size: 'Desktop', |
| browser: 'Chrome', |
| browser_version: '14.0.7', |
| operating_system: 'Windows', |
| operating_system_version: '11' |
| }, |
| { |
| user_id: 1, |
| name: 'purchase', |
| revenue_reporting_amount: '23', |
| revenue_reporting_currency: 'EUR' |
| }, |
| { |
| user_id: 2, |
| name: 'pageview', |
| screen_size: 'Desktop', |
| browser: 'Chrome', |
| browser_version: '14.0.7', |
| operating_system: 'Windows', |
| operating_system_version: '11' |
| }, |
| { |
| user_id: 3, |
| name: 'pageview', |
| screen_size: 'Mobile', |
| browser: 'Firefox', |
| browser_version: '98', |
| operating_system: 'MacOS', |
| operating_system_version: '10.15' |
| }, |
| { |
| user_id: 3, |
| name: 'purchase', |
| revenue_reporting_amount: '12345.67', |
| revenue_reporting_currency: 'EUR' |
| } |
| ] |
| }) |
|
|
| await addCustomGoal({ page, domain, name: 'purchase', currency: 'EUR' }) |
|
|
| await page.goto('/' + domain + '?f=is,goal,purchase', { |
| waitUntil: 'commit' |
| }) |
|
|
| const report = page.getByTestId('report-devices') |
|
|
| await test.step('browsers report shows conversions for revenue goal', async () => { |
| await tabButton(report, 'Browsers').click() |
| await report.getByTestId('report-end').scrollIntoViewIfNeeded() |
|
|
| await expectHeaders(report, ['Browser', 'Conversions', 'CR']) |
|
|
| await expectRows(report, ['Chrome', 'Firefox']) |
|
|
| await expectMetricValues(report, 'Chrome', ['1', '50%']) |
| await expectMetricValues(report, 'Firefox', ['1', '100%']) |
| }) |
|
|
| await test.step('browsers details modal includes revenue columns', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Browsers' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Browser', |
| /Total visitors/, |
| /Conversions/, |
| /CR/, |
| /Revenue/, |
| /Average/ |
| ]) |
|
|
| await expectRows(modal(page), ['Chrome', 'Firefox']) |
|
|
| await expectMetricValues(modal(page), 'Chrome', [ |
| '2', |
| '1', |
| '50%', |
| '€23.0', |
| '€23.0' |
| ]) |
| await expectMetricValues(modal(page), 'Firefox', [ |
| '1', |
| '1', |
| '100%', |
| '€12.3K', |
| '€12.3K' |
| ]) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('browser versions report shows conversions for revenue goal', async () => { |
| await rowLink(report, 'Chrome').click() |
|
|
| await expect(page).toHaveURL(/f=is,browser,Chrome/) |
|
|
| await expectHeaders(report, ['Browser version', 'Conversions', 'CR']) |
|
|
| await expectRows(report, ['Chrome 14.0.7']) |
|
|
| await expectMetricValues(report, 'Chrome 14.0.7', ['1', '50%']) |
| }) |
|
|
| await test.step('browser versions details modal includes revenue columns', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Browser versions' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Browser version', |
| /Total visitors/, |
| /Conversions/, |
| /CR/, |
| /Revenue/, |
| /Average/ |
| ]) |
|
|
| await expectRows(modal(page), ['14.0.7']) |
|
|
| await expectMetricValues(modal(page), '14.0.7', [ |
| '2', |
| '1', |
| '50%', |
| '€23.0', |
| '€23.0' |
| ]) |
|
|
| await closeModalButton(page).click() |
|
|
| await page |
| .getByRole('button', { name: 'Remove filter: Browser is Chrome' }) |
| .click() |
| }) |
|
|
| await test.step('operating systems report shows conversions for revenue goal', async () => { |
| await tabButton(report, 'Operating systems').click() |
|
|
| await expectHeaders(report, ['Operating system', 'Conversions', 'CR']) |
|
|
| await expectRows(report, ['MacOS', 'Windows']) |
|
|
| await expectMetricValues(report, 'MacOS', ['1', '100%']) |
| await expectMetricValues(report, 'Windows', ['1', '50%']) |
| }) |
|
|
| await test.step('operating systems details modal includes revenue columns', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Operating systems' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Operating system', |
| /Total visitors/, |
| /Conversions/, |
| /CR/, |
| /Revenue/, |
| /Average/ |
| ]) |
|
|
| await expectRows(modal(page), ['MacOS', 'Windows']) |
|
|
| await expectMetricValues(modal(page), 'MacOS', [ |
| '1', |
| '1', |
| '100%', |
| '€12.3K', |
| '€12.3K' |
| ]) |
| await expectMetricValues(modal(page), 'Windows', [ |
| '2', |
| '1', |
| '50%', |
| '€23.0', |
| '€23.0' |
| ]) |
|
|
| await closeModalButton(page).click() |
| }) |
|
|
| await test.step('operating system versions report shows conversions for revenue goal', async () => { |
| await rowLink(report, 'Windows').click() |
|
|
| await expect(page).toHaveURL(/f=is,os,Windows/) |
|
|
| await expectHeaders(report, [ |
| 'Operating system version', |
| 'Conversions', |
| 'CR' |
| ]) |
|
|
| await expectRows(report, ['Windows 11']) |
|
|
| await expectMetricValues(report, 'Windows 11', ['1', '50%']) |
| }) |
|
|
| await test.step('operating system versions details modal includes revenue columns', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Operating system versions' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Operating system version', |
| /Total visitors/, |
| /Conversions/, |
| /CR/, |
| /Revenue/, |
| /Average/ |
| ]) |
|
|
| await expectRows(modal(page), ['11']) |
|
|
| await expectMetricValues(modal(page), '11', [ |
| '2', |
| '1', |
| '50%', |
| '€23.0', |
| '€23.0' |
| ]) |
|
|
| await closeModalButton(page).click() |
|
|
| await page |
| .getByRole('button', { |
| name: 'Remove filter: Operating system is Windows' |
| }) |
| .click() |
| }) |
|
|
| await test.step('devices report shows conversions for revenue goal', async () => { |
| await tabButton(report, 'Devices').click() |
|
|
| await expectHeaders(report, ['Device', 'Conversions', 'CR']) |
|
|
| await expectRows(report, ['Desktop', 'Mobile']) |
|
|
| await expectMetricValues(report, 'Desktop', ['1', '50%']) |
| await expectMetricValues(report, 'Mobile', ['1', '100%']) |
| }) |
|
|
| await test.step('devices details modal includes revenue columns', async () => { |
| await detailsLink(report).click() |
|
|
| await expect( |
| modal(page).getByRole('heading', { name: 'Devices' }) |
| ).toBeVisible() |
|
|
| await expectHeaders(modal(page), [ |
| 'Device', |
| /Total visitors/, |
| /Conversions/, |
| /CR/, |
| /Revenue/, |
| /Average/ |
| ]) |
|
|
| await expectRows(modal(page), ['Desktop', 'Mobile']) |
|
|
| await expectMetricValues(modal(page), 'Desktop', [ |
| '2', |
| '1', |
| '50%', |
| '€23.0', |
| '€23.0' |
| ]) |
| await expectMetricValues(modal(page), 'Mobile', [ |
| '1', |
| '1', |
| '100%', |
| '€12.3K', |
| '€12.3K' |
| ]) |
|
|
| await closeModalButton(page).click() |
| }) |
| }) |
|
|