Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: playwright 16 #28994

Merged
merged 15 commits into from
Feb 21, 2025
66 changes: 1 addition & 65 deletions cypress/e2e/events.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,73 +29,9 @@ describe('Events', () => {
cy.visit('/activity/explore')
})

it('Events loaded', () => {
cy.get('.DataTable').should('exist')
})

/** keeping this because it works locally in playwright but not in CI */
it('Click on an event', () => {
cy.get('.DataTable [data-row-key]:nth-child(2) td:first-child').click()
cy.get('[data-attr=event-details]').should('exist')
})

it('Apply 1 overall filter', () => {
cy.get('[data-attr="new-prop-filter-EventPropertyFilters.0"]').click()
cy.get('[data-attr=taxonomic-filter-searchfield]').click()
cy.get('[data-attr=prop-filter-event_properties-0]').click()
cy.get('[data-attr=prop-val]').click({ force: true })
cy.wait('@getBrowserValues').then(() => {
cy.get('[data-attr=prop-val-0]').click()
cy.get('.DataTable').should('exist')
})
})

it('separates feature flag properties into their own tab', () => {
cy.get('[data-attr="new-prop-filter-EventPropertyFilters.0"]').click()
cy.get('[data-attr="taxonomic-tab-event_feature_flags"]').should('contain.text', 'Feature flags: 2').click()
// some virtualized rows remain in the dom, but hidden
cy.get('.taxonomic-list-row:visible').should('have.length', 2)
})

it('use before and after with a DateTime property', () => {
// Select the time property
cy.get('[data-attr="new-prop-filter-EventPropertyFilters.0"]').click()
cy.get('[data-attr=taxonomic-filter-searchfield]').type('$time')
cy.get('.taxonomic-list-row').should('have.length', 1)
cy.get('[data-attr=prop-filter-event_properties-0]').click({ force: true })

cy.get('[data-attr="taxonomic-operator"]').click()
cy.get('.operator-value-option').should('contain.text', '> after')
cy.get('.operator-value-option').should('contain.text', '< before')
})

it('use less than and greater than with a numeric property', () => {
cy.get('[data-attr="new-prop-filter-EventPropertyFilters.0"]').click()
cy.get('[data-attr=taxonomic-filter-searchfield]').type('$browser_version')
cy.get('.taxonomic-list-row').should('have.length', 1).click()

cy.get('[data-attr="taxonomic-operator"]').click()
cy.get('.operator-value-option').its('length').should('eql', 11) // 10 + 1 for the label in the LemonSelect button
cy.get('.operator-value-option').contains('< less than').should('be.visible')
cy.get('.operator-value-option').contains('> greater than').should('be.visible')
})

it('adds and removes an additional column', () => {
cy.get('[data-attr=events-table-column-selector]').click()
cy.get('[data-attr=taxonomic-filter-searchfield]').type('$browser_version')
cy.get('.taxonomic-list-row').should('have.length', 1).click()
cy.get('.SelectedColumn').should('have.length', 7)
cy.get('[data-attr=column-display-item-remove-icon').last().click()
cy.get('.SelectedColumn').should('have.length', 6)
})

it('keeps the popop open after selecting an option', () => {
cy.get('[data-attr="new-prop-filter-EventPropertyFilters.0"]').click()
cy.get('[data-attr=taxonomic-filter-searchfield]').type('$browser_version')
cy.get('.taxonomic-list-row').should('have.length', 1).click()

cy.get('[data-attr="taxonomic-operator"]').click()
cy.get('.operator-value-option').contains('> greater than').click()
cy.wait(500)
cy.get('[data-attr="taxonomic-operator"]').should('be.visible')
})
})
2 changes: 1 addition & 1 deletion playwright/e2e/billing/billing-limits.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type BillingRouteHandlers = {
async function setupBillingRoutes(page: Page, handlers: BillingRouteHandlers): Promise<void> {
await page.route('**/api/billing/', async (route) => {
const method = route.request().method()
const filePath = path.join(__dirname, '../../mocks/billing.json')
const filePath = path.join(__dirname, '../../mocks/billing/billing.json')
let billingContent = JSON.parse(fs.readFileSync(filePath, 'utf-8'))

if (method === 'GET') {
Expand Down
4 changes: 2 additions & 2 deletions playwright/e2e/billing/billing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ test.describe('Billing', () => {
// We'll read the JSON from a fixture folder. Adjust the path as needed.
await page.route('**/api/billing/', async (route) => {
// If your codebase uses a different structure, update accordingly
const filePath = path.join(__dirname, '../../mocks/billing.json')
const filePath = path.join(__dirname, '../../mocks/billing/billing.json')
const billingContent = fs.readFileSync(filePath, 'utf-8')
await route.fulfill({
status: 200,
Expand All @@ -24,7 +24,7 @@ test.describe('Billing', () => {
test('Show and submit unsubscribe survey', async ({ page }) => {
// Intercept the specific unsubscribe request
await page.route('**/api/billing/deactivate?products=product_analytics', async (route) => {
const filePath = path.join(__dirname, '../../mocks/billing-unsubscribed-product-analytics.json')
const filePath = path.join(__dirname, '../../mocks/billing/billing-unsubscribed-product-analytics.json')
const unsubscribedContent = fs.readFileSync(filePath, 'utf-8')
await route.fulfill({
status: 200,
Expand Down
127 changes: 127 additions & 0 deletions playwright/e2e/events.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import path from 'path'

import { expect, test } from '../utils/playwright-test-base'

test.describe('Events', () => {
test.beforeEach(async ({ page }) => {
await page.route('/api/event/values?key=%24browser', (route) =>
route.fulfill({
status: 200,
body: JSON.stringify([{ name: '96' }, { name: '97' }]),
})
)

await page.route('/api/projects/@current/property_definitions/?limit=5000', (route) =>
route.fulfill({
status: 200,
path: path.resolve(__dirname, '../mocks/events/property_definitions.json'),
})
)

await page.route('/api/projects/*/property_definitions?is_feature_flag=false&search=&*', (route) =>
route.fulfill({
status: 200,
path: path.resolve(__dirname, '../mocks/events/property_definitions.json'),
})
)

await page.route('/api/projects/*/property_definitions?is_feature_flag=false&search=%24time*', (route) =>
route.fulfill({
status: 200,
path: path.resolve(__dirname, '../mocks/events/only_time_property_definition.json'),
})
)

await page.route('/api/projects/*/property_definitions?is_feature_flag=false&search=%24browser*', (route) =>
route.fulfill({
status: 200,
path: path.resolve(__dirname, '../mocks/events/only_browser_version_property_definition.json'),
})
)

await page.route('/api/projects/*/property_definitions?is_feature_flag=true*', (route) =>
route.fulfill({
status: 200,
path: path.resolve(__dirname, '../mocks/events/feature_flag_property_definition.json'),
})
)

await page.route('/api/event/values/?key=$browser_version', (route) =>
route.fulfill({
status: 200,
body: JSON.stringify([{ name: '96' }, { name: '97' }]),
})
)

await page.goToMenuItem('activity')
await page.waitForURL('**/activity/explore')
})

/** works locally but not in CI - in CI the event list is never loading */
test.skip('Click on an event', async ({ page }) => {
await expect(page.locator('.DataTable .DataTable__row').first()).toBeVisible()
await page.locator('.DataTable .DataTable__row .LemonTable__toggle').first().click()
await expect(page.locator('[data-attr=event-details]')).toBeVisible()
})

test('Apply 1 overall filter', async ({ page }) => {
await page.locator('[data-attr="new-prop-filter-EventPropertyFilters.0"]').click()
await page.locator('[data-attr=taxonomic-filter-searchfield]').click()
await page.locator('[data-attr=prop-filter-event_properties-0]').click()
await page.locator('[data-attr=prop-val]').click({ force: true })
await page.waitForResponse('/api/event/values?key=%24browser')
await page.locator('[data-attr=prop-val-0]').click()
await expect(page.locator('.DataTable')).toBeVisible()
})

test('Separates feature flag properties into their own tab', async ({ page }) => {
await page.locator('[data-attr="new-prop-filter-EventPropertyFilters.0"]').click()
await expect(page.locator('[data-attr="taxonomic-tab-event_feature_flags"]')).toContainText('Feature flags: 2')
await page.locator('[data-attr="taxonomic-tab-event_feature_flags"]').click()
await expect(page.locator('.taxonomic-list-row:visible')).toHaveCount(2)
})

test('Use before and after with a DateTime property', async ({ page }) => {
await page.locator('[data-attr="new-prop-filter-EventPropertyFilters.0"]').click()
await page.locator('[data-attr=taxonomic-filter-searchfield]').type('$time')
await expect(page.locator('.taxonomic-list-row')).toHaveCount(1)
await page.locator('[data-attr=prop-filter-event_properties-0]').click({ force: true })

await page.locator('[data-attr="taxonomic-operator"]').click()
await expect(page.getByRole('menuitem', { name: '> after' })).toBeVisible()
await expect(page.getByRole('menuitem', { name: '< before' })).toBeVisible()
})

test('Use less than and greater than with a numeric property', async ({ page }) => {
await page.locator('[data-attr="new-prop-filter-EventPropertyFilters.0"]').click()
await page.locator('[data-attr=taxonomic-filter-searchfield]').type('$browser_version')
await expect(page.locator('.taxonomic-list-row')).toHaveCount(1)
await page.locator('.taxonomic-list-row').click()

await page.locator('[data-attr="taxonomic-operator"]').click()
await expect(page.locator('.operator-value-option')).toHaveCount(11) // 10 + 1 for the label in the LemonSelect button
await expect(page.getByRole('menuitem', { name: '< less than' })).toBeVisible()
await expect(page.getByRole('menuitem', { name: '> greater than' })).toBeVisible()
})

test('Adds and removes an additional column', async ({ page }) => {
await page.locator('[data-attr=events-table-column-selector]').click()
await page.locator('[data-attr=taxonomic-filter-searchfield]').type('$browser_version')
await expect(page.locator('.taxonomic-list-row')).toHaveCount(1)
await page.locator('.taxonomic-list-row').click()
await expect(page.locator('.SelectedColumn')).toHaveCount(7)
await page.locator('[data-attr=column-display-item-remove-icon]').last().click()
await expect(page.locator('.SelectedColumn')).toHaveCount(6)
})

test('Keeps the popup open after selecting an option', async ({ page }) => {
await page.locator('[data-attr="new-prop-filter-EventPropertyFilters.0"]').click()
await page.locator('[data-attr=taxonomic-filter-searchfield]').type('$browser_version')
await expect(page.locator('.taxonomic-list-row')).toHaveCount(1)
await page.locator('.taxonomic-list-row').click()

await page.locator('[data-attr="taxonomic-operator"]').click()
await page.getByRole('menuitem', { name: '> greater than' }).click()
await expect(page.locator('[data-attr="taxonomic-operator"]')).toBeVisible()
})
})
File renamed without changes.
23 changes: 23 additions & 0 deletions playwright/mocks/events/feature_flag_property_definition.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": "017dde0e-1cb5-0000-68b4-44835b7c894f",
"name": "$feature/awesome-new-hidden-thing",
"is_numerical": false,
"query_usage_30_day": null,
"property_type": null,
"is_seen_on_filtered_events": null
},
{
"id": "017dde0e-1cb5-0000-68b4-44835b7c894f",
"name": "$feature/our-cool-experiment",
"is_numerical": false,
"query_usage_30_day": null,
"property_type": null,
"is_seen_on_filtered_events": null
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "017dde0e-1cb5-0000-68b4-44835b7c894f",
"name": "$browser_version",
"is_numerical": true,
"query_usage_30_day": null,
"property_type": null,
"is_seen_on_filtered_events": null
}
]
}
15 changes: 15 additions & 0 deletions playwright/mocks/events/only_time_property_definition.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "017dde0e-1cc9-0000-ed91-26909937767f",
"name": "$time",
"is_numerical": true,
"query_usage_30_day": null,
"property_type": "DateTime",
"is_seen_on_filtered_events": null
}
]
}
23 changes: 23 additions & 0 deletions playwright/mocks/events/property_definitions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": "017dde0e-1cb5-0000-68b4-44835b7c894f",
"name": "$browser",
"is_numerical": true,
"query_usage_30_day": null,
"property_type": null,
"is_seen_on_filtered_events": null
},
{
"id": "017dde0e-1cc9-0000-ed91-26909937767f",
"name": "$time",
"is_numerical": true,
"query_usage_30_day": null,
"property_type": "DateTime",
"is_seen_on_filtered_events": null
}
]
}
Loading
Loading