Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
956a6dc
Add helper for adding custom goal and use it in a new test
zoldar Feb 11, 2026
adfda52
Extend and add goal helpers to support all goal types
zoldar Feb 12, 2026
0ff7322
Add intro tests
zoldar Feb 12, 2026
3f4c968
Add js-joda for time manipulation in tests
zoldar Feb 12, 2026
ad2819f
Properly test for different time ranges
zoldar Feb 16, 2026
16343b2
Test graph intervals
zoldar Feb 16, 2026
ee2a2d3
Test comparing stats over time
zoldar Feb 16, 2026
133e442
Split filter tests into a separate context and cover page related ones
zoldar Feb 17, 2026
b23c605
Add hostname filter test
zoldar Feb 17, 2026
4082ccd
Add goal filter tests
zoldar Feb 17, 2026
88cd031
Add property filtering tests
zoldar Feb 17, 2026
e57a300
Remove unnecessary assertions for goal setup fixtures
zoldar Feb 18, 2026
016742f
Add tests for all acquisition related filters
zoldar Feb 19, 2026
a5f4e12
Add tests for filtering by location
zoldar Feb 19, 2026
1530c79
Shorten test timeout for local dev env from 30s to 10s
zoldar Feb 19, 2026
7b91b71
Add (broken) test for screen size filtering
zoldar Feb 19, 2026
5fb379e
Add missing type definitions in frontend event fixture
zoldar Feb 19, 2026
5cc9ecf
Test filtering by browser
zoldar Feb 19, 2026
d41910f
Test operating system filters (broken the same way as screen size)
zoldar Feb 19, 2026
0c489da
WIP
zoldar Feb 23, 2026
b0c3b5c
Add remaining time related tests
zoldar Feb 23, 2026
a8f5016
Add tests for site switcher
zoldar Feb 23, 2026
a94be7e
Add breakdown tests
zoldar Feb 24, 2026
f5c9b6c
Add more breakdown tests
zoldar Feb 24, 2026
3369e40
Move some of the helpers to `test-utils`
zoldar Feb 24, 2026
2dc30b9
Add behaviour tests along with fixtures for custom props and funnels
zoldar Feb 25, 2026
ba5f4bf
Extend behaviour tests
zoldar Feb 25, 2026
60b3046
Test breakdown layout change (report and modal) for goals in filters
zoldar Feb 25, 2026
96a6275
Add more detailed modal tests
zoldar Feb 26, 2026
77aa116
Add modal tests to breakdowns
zoldar Feb 26, 2026
bc90914
Add modal tests to behaviours
zoldar Feb 26, 2026
91a23ed
Test funnels tab dropdown
zoldar Feb 26, 2026
e5a2ef2
Test props dropdown search
zoldar Feb 26, 2026
fd006c0
Test current realtime visitors counter in top stats
zoldar Mar 1, 2026
b96e962
Move filter helpers to test-utils for reuse in segments tests
zoldar Mar 1, 2026
3ff2f72
Add one more filter helper
zoldar Mar 1, 2026
8afe5af
Test creating personal segment
zoldar Mar 1, 2026
0bddfdb
Fix existing tests
zoldar Mar 2, 2026
ff68d86
Test adding site segments
zoldar Mar 2, 2026
9b496c3
Test combining filters and segments
zoldar Mar 2, 2026
a22bd1a
Remove commented out, brittle version of `addFunnel` fixture
zoldar Mar 2, 2026
0d4e038
Test editing existing segment
zoldar Mar 2, 2026
7289868
Test saving segment as new
zoldar Mar 2, 2026
0f9e7f2
Test deleting segment
zoldar Mar 2, 2026
ea06855
Test closing edited segment without saving
zoldar Mar 2, 2026
b033f89
Fix type signature ofr MovePeriodArrows
zoldar Mar 2, 2026
7481532
Fix formatting
zoldar Mar 2, 2026
e9bc0c9
Don't include backend E2E logic in CE
zoldar Mar 2, 2026
b63f78d
Increase the number of E2E CI shards from 2 to 4
zoldar Mar 2, 2026
1a5181b
Fix problematic test cases
zoldar Mar 2, 2026
da44dfc
Move general tests under `dashboard/` and remove redundant cases
zoldar Mar 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/elixir.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ jobs:
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2]
shardTotal: [2]
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
steps:
- uses: actions/checkout@v6
with:
Expand Down
5 changes: 4 additions & 1 deletion assets/js/dashboard/components/filter-operator-selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ export default function FilterOperatorSelector(props) {
ref={buttonRef}
className="relative flex justify-between items-center w-full rounded-md border border-gray-300 dark:border-gray-750 px-4 py-2 bg-white dark:bg-gray-750 text-sm text-gray-700 dark:text-gray-200 dark:hover:bg-gray-700 focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 dark:focus:ring-offset-gray-900 focus:ring-indigo-500 text-left"
>
{FILTER_OPERATIONS_DISPLAY_NAMES[props.selectedType]}
<span data-testid="filter-operator">
{FILTER_OPERATIONS_DISPLAY_NAMES[props.selectedType]}
</span>
<ChevronDownIcon
className="-mr-2 ml-2 h-4 w-4 text-gray-500 dark:text-gray-400"
aria-hidden="true"
Expand Down Expand Up @@ -63,6 +65,7 @@ export default function FilterOperatorSelector(props) {
.filter(([_operation, supported]) => supported)
.map(([operation]) => (
<button
data-testid="filter-operator-option"
key={operation}
data-selected={operation === props.selectedType}
onClick={(e) => {
Expand Down
1 change: 1 addition & 0 deletions assets/js/dashboard/components/search-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export const SearchInput = ({
/>
<div className={classNames('relative max-w-64 w-full', className)}>
<input
data-testid="search-input"
onBlur={() => setIsFocused(false)}
onFocus={() => setIsFocused(true)}
ref={searchRef}
Expand Down
2 changes: 2 additions & 0 deletions assets/js/dashboard/components/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const TableHeaderCell = ({
}) => {
return (
<th
data-testid="report-header"
className={classNames(
'p-2 text-xs font-semibold text-gray-500 dark:text-gray-400',
className
Expand Down Expand Up @@ -105,6 +106,7 @@ export const ItemRow = <T extends Record<string, string | number | ReactNode>>({

return (
<tr
data-testid="report-row"
className="group text-sm dark:text-gray-200 md:cursor-default cursor-pointer"
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
Expand Down
5 changes: 4 additions & 1 deletion assets/js/dashboard/components/tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ const TabButtonText = ({
'text-gray-900 dark:text-gray-100 font-bold tracking-[-.01em]': active
})}
>
{children}
<span data-active={active ? 'true' : 'false'} data-testid="tab-button">
{children}
</span>
</span>
)

Expand Down Expand Up @@ -183,6 +185,7 @@ const Items = ({ options, searchable, closeDropdown }: ItemsProps) => {
</div>
)}
<div
data-testid="dropdown-items"
className={'max-h-[224px] overflow-y-auto flex flex-col gap-y-0.5 p-1'}
>
{showableData.map(({ selected, label, onClick }, index) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ export const DashboardPeriodMenu = ({
<>
<BlurMenuButtonOnEscape targetRef={buttonRef} />
<Popover.Button ref={buttonRef} className={datemenuButtonClassName}>
<span className={popover.toggleButton.classNames.truncatedText}>
<span
data-testid="current-query-period"
className={popover.toggleButton.classNames.truncatedText}
>
{getCurrentPeriodDisplayName({ dashboardState, site })}
</span>
<DateMenuChevron />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ export function DashboardPeriodPicker({ className }: { className?: string }) {
const compareCalendarButtonRef = useRef<HTMLButtonElement>(null)

return (
<div className={classNames('flex shrink-0', className)}>
<div
data-testid="query-period-picker"
className={classNames('flex shrink-0', className)}
>
<MovePeriodArrows className={isComparing ? 'hidden md:flex' : ''} />
<Popover className="min-w-36 md:relative lg:w-48">
{({ close }) => (
Expand Down
15 changes: 13 additions & 2 deletions assets/js/dashboard/nav-menu/query-periods/move-period-arrows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,17 @@ const ArrowKeybind = ({
}

function ArrowIcon({
testId,
direction,
disabled = false
}: {
testId?: string
direction: 'left' | 'right'
disabled?: boolean
}) {
return (
<svg
data-testid={testId}
className={classNames(
'feather size-4',
disabled
Expand Down Expand Up @@ -117,7 +120,11 @@ export function MovePeriodArrows({ className }: { className?: string }) {
: (search) => search
}
>
<ArrowIcon direction="left" disabled={!canGoBack} />
<ArrowIcon
testId="period-move-back"
direction="left"
disabled={!canGoBack}
/>
</AppNavigationLink>
<AppNavigationLink
className={classNames(sharedClass, 'rounded-r', {
Expand All @@ -135,7 +142,11 @@ export function MovePeriodArrows({ className }: { className?: string }) {
: (search) => search
}
>
<ArrowIcon direction="right" disabled={!canGoForward} />
<ArrowIcon
testId="period-move-forward"
direction="right"
disabled={!canGoForward}
/>
</AppNavigationLink>
{!!dashboardRouteMatch && <ArrowKeybind keyboardKey="ArrowLeft" />}
{!!dashboardRouteMatch && <ArrowKeybind keyboardKey="ArrowRight" />}
Expand Down
1 change: 1 addition & 0 deletions assets/js/dashboard/nav-menu/segments/segment-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export const SegmentMenu = () => {
)}
>
<ChevronDownIcon
data-testid="segmentmenu"
className="w-4 h-4 md:h-5 md:w-5 block"
aria-hidden="true"
/>
Expand Down
5 changes: 4 additions & 1 deletion assets/js/dashboard/site-switcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ export const SiteSwitcher = () => {
className="block h-4 w-4 mx-1"
/>
)}
<span className={'truncate hidden sm:block sm:mr-1 lg:mr-0'}>
<span
data-testid="site-switcher-current-site"
className={'truncate hidden sm:block sm:mr-1 lg:mr-0'}
>
{currentSite.isConsolidatedView
? 'All sites'
: currentSite.domain}
Expand Down
2 changes: 1 addition & 1 deletion assets/js/dashboard/stats/behaviours/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ function Behaviours({ importedDataInView, setMode, mode }) {
}

return (
<ReportLayout className="col-span-full">
<ReportLayout testId="report-behaviours" className="col-span-full">
<ReportHeader>
<div className="flex gap-x-2">
<TabWrapper>
Expand Down
4 changes: 2 additions & 2 deletions assets/js/dashboard/stats/devices/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ function OperatingSystemVersions({ afterFetchData }) {
renderIcon={renderIcon}
afterFetchData={afterFetchData}
getFilterInfo={getFilterInfo}
keyLabel="Operating System Version"
keyLabel="Operating system version"
metrics={chooseMetrics()}
/>
)
Expand Down Expand Up @@ -503,7 +503,7 @@ export default function Devices() {
}

return (
<ReportLayout className="overflow-x-hidden">
<ReportLayout testId="report-devices" className="overflow-x-hidden">
<ReportHeader>
<div className="flex gap-x-3">
<TabWrapper>
Expand Down
8 changes: 6 additions & 2 deletions assets/js/dashboard/stats/graph/interval-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ export function IntervalPicker({
'rounded-sm text-sm flex items-center'
)}
>
{INTERVAL_LABELS[currentInterval]}
<span data-testid="current-graph-interval">
{INTERVAL_LABELS[currentInterval]}
</span>
<ChevronDownIcon className="ml-1 h-4 w-4" aria-hidden="true" />
</Popover.Button>

Expand Down Expand Up @@ -187,7 +189,9 @@ export function IntervalPicker({
'w-full text-left'
)}
>
{INTERVAL_LABELS[option]}
<span data-testid="graph-interval">
{INTERVAL_LABELS[option]}
</span>
</button>
))}
</Popover.Panel>
Expand Down
5 changes: 4 additions & 1 deletion assets/js/dashboard/stats/graph/top-stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,10 @@ export default function TopStats({

{isComparison ? (
<div>
<p className="font-bold text-xl text-gray-500 dark:text-gray-400">
<p
id={`previous-${stat.graph_metric}`}
className="font-bold text-xl text-gray-500 dark:text-gray-400"
>
{topStatNumberShort(stat.graph_metric, stat.comparison_value)}
</p>
<p className="text-xs text-gray-500 dark:text-gray-400">
Expand Down
1 change: 1 addition & 0 deletions assets/js/dashboard/stats/locations/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ class Locations extends React.Component {
render() {
return (
<ReportLayout
testId="report-locations"
className={this.state.mode === 'map' ? '' : 'overflow-x-hidden'}
>
<ReportHeader>
Expand Down
2 changes: 2 additions & 0 deletions assets/js/dashboard/stats/modals/filter-modal-group.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export default function FilterModalGroup({
{rows.map(({ id, filter }) =>
filterGroup === 'props' ? (
<FilterModalPropsRow
testId={id}
key={id}
filter={filter}
showDelete={rows.length > 1}
Expand All @@ -55,6 +56,7 @@ export default function FilterModalGroup({
/>
) : (
<FilterModalRow
testId={id}
key={id}
filter={filter}
labels={labels}
Expand Down
6 changes: 5 additions & 1 deletion assets/js/dashboard/stats/modals/filter-modal-props-row.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { useDashboardStateContext } from '../../dashboard-state-context'
import { useSiteContext } from '../../site-context'

export default function FilterModalPropsRow({
testId,
filter,
showDelete,
disabledOptions,
Expand Down Expand Up @@ -75,7 +76,10 @@ export default function FilterModalPropsRow({
}

return (
<div className="grid grid-cols-12 mt-6">
<div
data-testid={`filter-row-${testId}`}
className="grid grid-cols-12 mt-6"
>
<div className="col-span-4">
<Combobox
className="mr-2"
Expand Down
2 changes: 2 additions & 0 deletions assets/js/dashboard/stats/modals/filter-modal-row.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useDashboardStateContext } from '../../dashboard-state-context'
import { useSiteContext } from '../../site-context'

export default function FilterModalRow({
testId,
filter,
labels,
canDelete,
Expand Down Expand Up @@ -72,6 +73,7 @@ export default function FilterModalRow({

return (
<div
data-testid={`filter-row-${testId}`}
className={classNames('grid mt-1', {
'grid-cols-12': canDelete,
'grid-cols-11': !canDelete
Expand Down
2 changes: 1 addition & 1 deletion assets/js/dashboard/stats/modals/referrer-drilldown.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function ReferrerDrilldownModal() {
BUILD_EXTRA && revenueAvailable(dashboardState, site)

const reportInfo = {
title: 'Referrer Drilldown',
title: 'Referrer drilldown',
dimension: 'referrer',
endpoint: url.apiPath(
site,
Expand Down
6 changes: 5 additions & 1 deletion assets/js/dashboard/stats/more-link.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ export default function MoreLink({ linkProps, state }) {

return (
<Tooltip info="View details" containerRef={portalRef}>
<AppNavigationLink {...linkProps} className={baseClassName}>
<AppNavigationLink
{...linkProps}
aria-label="View details"
className={baseClassName}
>
{icon}
</AppNavigationLink>
</Tooltip>
Expand Down
2 changes: 1 addition & 1 deletion assets/js/dashboard/stats/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export default function Pages() {
}

return (
<ReportLayout className="overflow-x-hidden">
<ReportLayout testId="report-pages" className="overflow-x-hidden">
<ReportHeader>
<div className="flex gap-x-3">
<TabWrapper>
Expand Down
6 changes: 5 additions & 1 deletion assets/js/dashboard/stats/reports/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ export default function ListReport<
.map((metric) => {
return (
<div
data-testid="report-header"
key={metric.key}
className={`${metric.key} text-right ${hiddenOnMobileClass(metric)}`}
style={{ minWidth: colMinWidth }}
Expand All @@ -260,7 +261,9 @@ export default function ListReport<

return (
<div className="pt-3 w-full text-xs font-medium text-gray-500 flex items-center dark:text-gray-400">
<span className="grow truncate">{keyLabel}</span>
<span data-testid="report-header" className="grow truncate">
{keyLabel}
</span>
{metricLabels}
</div>
)
Expand All @@ -280,6 +283,7 @@ export default function ListReport<
return (
<div key={listItem.name} style={{ minHeight: ROW_HEIGHT }}>
<div
data-testid="report-row"
className="group/row flex w-full items-center hover:bg-gray-100/60 dark:hover:bg-gray-850 rounded-sm md:cursor-default cursor-pointer"
style={{ marginTop: ROW_GAP_HEIGHT }}
onClick={handleRowClick}
Expand Down
7 changes: 6 additions & 1 deletion assets/js/dashboard/stats/reports/report-layout.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import React from 'react'
import classNames from 'classnames'

export function ReportLayout({ children, className = undefined }) {
export function ReportLayout({
children,
testId = undefined,
className = undefined
}) {
return (
<div
data-testid={testId}
className={classNames(
'relative min-h-[430px] w-full p-5 flex flex-col bg-white dark:bg-gray-900 shadow-sm rounded-md md:min-h-initial md:h-27.25rem',
className
Expand Down
2 changes: 1 addition & 1 deletion assets/js/dashboard/stats/sources/referrer-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export default function Referrers({ source }) {
}

return (
<ReportLayout className="overflow-x-hidden">
<ReportLayout testId="report-referrers" className="overflow-x-hidden">
<ReportHeader>
<div className="flex gap-x-3">
<TabWrapper>
Expand Down
2 changes: 1 addition & 1 deletion assets/js/dashboard/stats/sources/source-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ export default function SourceList() {
}

return (
<ReportLayout className="overflow-x-hidden">
<ReportLayout testId="report-sources" className="overflow-x-hidden">
<ReportHeader>
<div className="flex gap-x-3">
<TabWrapper>
Expand Down
Loading
Loading