diff --git a/.github/workflows/cypress-component.yml b/.github/workflows/cypress-component.yml new file mode 100644 index 00000000000..4e2e702ddf5 --- /dev/null +++ b/.github/workflows/cypress-component.yml @@ -0,0 +1,60 @@ +name: Cypress Component + +on: + - pull_request + +jobs: + cypress-component: + name: Cypress component tests + runs-on: ubuntu-18.04 + steps: + - name: Checkout + uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: 14 + - name: Get yarn cache directory path + id: yarn-dep-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + - uses: actions/cache@v1 + name: Setup Yarn dep cache + id: yarn-dep-cache + with: + path: ${{ steps.yarn-dep-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-dep-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn-dep- + - name: Yarn install deps + run: | + yarn install --frozen-lockfile; yarn add cypress@6.4.0 + - uses: actions/cache@v1 + name: Setup Yarn build cache + id: yarn-build-cache + with: + path: frontend/dist + key: ${{ runner.os }}-yarn-build-${{ hashFiles('frontend/src/') }} + restore-keys: | + ${{ runner.os }}-yarn-build- + - name: Yarn build + run: | + yarn build + if: steps.yarn-build-cache.outputs.cache-hit != 'true' + - name: Cypress run + uses: cypress-io/github-action@v2 + with: + config-file: cypress.json + record: true + parallel: true + group: 'PostHog Component' + env: + # pass the Dashboard record key as an environment variable + CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} + # Recommended: pass the GitHub token lets this action correctly + # determine the unique run id necessary to re-run the checks + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Archive test screenshots + uses: actions/upload-artifact@v1 + with: + name: screenshots + path: cypress/screenshots + if: ${{ failure() }} diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 9247f793808..b5c89e96c2f 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -5,7 +5,7 @@ on: jobs: cypress: - name: Cypress tests + name: Cypress E2E tests runs-on: ubuntu-18.04 strategy: # when one test fails, DO NOT cancel the other @@ -76,7 +76,7 @@ jobs: - name: Yarn install deps run: | yarn install --frozen-lockfile - yarn add cypress@5.3.0 cypress-terminal-report@2.1.0 + yarn add cypress@6.4.0 cypress-terminal-report@2.1.0 - uses: actions/cache@v1 name: Setup Yarn build cache id: yarn-build-cache @@ -108,7 +108,7 @@ jobs: - name: Cypress run uses: cypress-io/github-action@v2 with: - config-file: cypress.json + config-file: cypress.e2e.json record: true parallel: true group: 'PostHog Frontend' diff --git a/bin/frontend-test-runner b/bin/e2e-test-runner similarity index 77% rename from bin/frontend-test-runner rename to bin/e2e-test-runner index f0204f04f5e..5aa5c729e80 100755 --- a/bin/frontend-test-runner +++ b/bin/e2e-test-runner @@ -7,6 +7,6 @@ DEBUG=1 DATABASE_URL=postgres://localhost:5432/posthog_e2e_test python manage.py DEBUG=1 DATABASE_URL=postgres://localhost:5432/posthog_e2e_test python manage.py setup_dev & yarn add cypress-terminal-report ./bin/start-frontend & -CYPRESS_BASE_URL=http://localhost:8080 npx cypress open & +CYPRESS_BASE_URL=http://localhost:8080 npx cypress open --config-file cypress.e2e.json & DEBUG=1 TEST=1 DATABASE_URL=postgres://localhost:5432/posthog_e2e_test python manage.py runserver 8080 -yarn remove cypress-terminal-report \ No newline at end of file +yarn remove cypress-terminal-report diff --git a/cypress.e2e.json b/cypress.e2e.json new file mode 100644 index 00000000000..a0a3405f310 --- /dev/null +++ b/cypress.e2e.json @@ -0,0 +1,9 @@ +{ + "video": false, + "baseUrl": "http://localhost:8000", + "defaultCommandTimeout": 20000, + "requestTimeout": 8000, + "pageLoadTimeout": 80000, + "projectId": "twojfp", + "retries": 2 +} diff --git a/cypress.json b/cypress.json index a0a3405f310..25765b995b5 100644 --- a/cypress.json +++ b/cypress.json @@ -1,9 +1,7 @@ { "video": false, - "baseUrl": "http://localhost:8000", - "defaultCommandTimeout": 20000, - "requestTimeout": 8000, - "pageLoadTimeout": 80000, - "projectId": "twojfp", - "retries": 2 + "experimentalComponentTesting": true, + "testFiles": "**/*cy-spec.js", + "componentFolder": "frontend/src", + "projectId": "twojfp" } diff --git a/cypress/fixtures/api/dashboard.json b/cypress/fixtures/api/dashboard.json new file mode 100644 index 00000000000..adbb84bf589 --- /dev/null +++ b/cypress/fixtures/api/dashboard.json @@ -0,0 +1,51 @@ +{ + "count": 4, + "next": null, + "previous": null, + "results": [ + { + "id": 7, + "name": "App Analytics", + "pinned": true, + "items": null, + "created_at": "2021-02-05T13:55:40.297406Z", + "created_by": null, + "is_shared": false, + "share_token": "w_MkBdFSPoOZdB1yIOvmOJn_iQtxCA", + "deleted": false + }, + { + "id": 5, + "name": "Default", + "pinned": true, + "items": null, + "created_at": "2021-02-05T13:55:31.501043Z", + "created_by": null, + "is_shared": false, + "share_token": "fpDJjZ0iRgptWJYg-_l5buldK--7t6C6P9pTEXBQcZo", + "deleted": false + }, + { + "id": 8, + "name": "Sales & Revenue", + "pinned": true, + "items": null, + "created_at": "2021-02-05T13:55:43.654638Z", + "created_by": null, + "is_shared": false, + "share_token": "Z5Qb6E1337KbuT3LpGlsbmb1AVAHrg", + "deleted": false + }, + { + "id": 6, + "name": "Web Analytics", + "pinned": true, + "items": null, + "created_at": "2021-02-05T13:55:33.570744Z", + "created_by": null, + "is_shared": false, + "share_token": "2sMrL2yoSFgSy-uQLVi48fGKtHvO_A", + "deleted": false + } + ] +} diff --git a/cypress/fixtures/api/event/sessions/demo_sessions.json b/cypress/fixtures/api/event/sessions/demo_sessions.json new file mode 100644 index 00000000000..98112acfd21 --- /dev/null +++ b/cypress/fixtures/api/event/sessions/demo_sessions.json @@ -0,0 +1,867 @@ +{ + "result": [ + { + "distinct_id": "01777279-ff1b-0051-1fbd-b89614430f72", + "global_session_id": 13, + "length": 100, + "start_time": "2021-02-04T13:55:33.831566Z", + "end_time": "2021-02-04T13:57:13.831602Z", + "event_count": 6, + "events": [ + { + "id": "92b8dee3-e044-4fa8-8ad2-265da5f301c0", + "distinct_id": "01777279-ff1b-0051-1fbd-b89614430f72", + "properties": {}, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:33.831566+00:00", + "person": "01777279-ff1b-0051-1fbd-b89614430f72", + "elements": [], + "elements_chain": "" + }, + { + "id": "2f98dfd9-36a7-4f21-987f-8ba453594341", + "distinct_id": "01777279-ff1b-0051-1fbd-b89614430f72", + "properties": {}, + "event": "installed_app", + "timestamp": "2021-02-04T13:55:33.831583+00:00", + "person": "01777279-ff1b-0051-1fbd-b89614430f72", + "elements": [], + "elements_chain": "" + }, + { + "id": "f62c64e0-5d74-4c54-b494-3e352444c70f", + "distinct_id": "01777279-ff1b-0051-1fbd-b89614430f72", + "properties": { + "$current_url": "https://hogflix/settings" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:48.831631+00:00", + "person": "01777279-ff1b-0051-1fbd-b89614430f72", + "elements": [], + "elements_chain": "" + }, + { + "id": "0236bc7a-baa0-415d-885e-b1ebb8e6885c", + "distinct_id": "01777279-ff1b-0051-1fbd-b89614430f72", + "properties": { + "$current_url": "https://hogflix/profile" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:56:03.831663+00:00", + "person": "01777279-ff1b-0051-1fbd-b89614430f72", + "elements": [], + "elements_chain": "" + }, + { + "id": "12f8baa1-8255-48bc-a9c2-b415ffa621be", + "distinct_id": "01777279-ff1b-0051-1fbd-b89614430f72", + "properties": { + "app_rating": 5 + }, + "event": "rated_app", + "timestamp": "2021-02-04T13:56:18.831693+00:00", + "person": "01777279-ff1b-0051-1fbd-b89614430f72", + "elements": [], + "elements_chain": "" + }, + { + "id": "0f7902bb-53c1-4561-9e4c-12ab3edd6cc2", + "distinct_id": "01777279-ff1b-0051-1fbd-b89614430f72", + "properties": { + "is_first_movie": true + }, + "event": "watched_movie", + "timestamp": "2021-02-04T13:57:13.831602+00:00", + "person": "01777279-ff1b-0051-1fbd-b89614430f72", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": null, + "session_recordings": [] + }, + { + "distinct_id": "01777279-ff1b-003e-70d7-fd45f1f1f43b", + "global_session_id": 12, + "length": 100, + "start_time": "2021-02-04T13:55:33.828731Z", + "end_time": "2021-02-04T13:57:13.828767Z", + "event_count": 6, + "events": [ + { + "id": "14d08f23-f177-4256-af57-ff1f90e00479", + "distinct_id": "01777279-ff1b-003e-70d7-fd45f1f1f43b", + "properties": {}, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:33.828731+00:00", + "person": "01777279-ff1b-003e-70d7-fd45f1f1f43b", + "elements": [], + "elements_chain": "" + }, + { + "id": "ca848c85-ac7e-49c5-b2aa-e010e608eb61", + "distinct_id": "01777279-ff1b-003e-70d7-fd45f1f1f43b", + "properties": {}, + "event": "installed_app", + "timestamp": "2021-02-04T13:55:33.828749+00:00", + "person": "01777279-ff1b-003e-70d7-fd45f1f1f43b", + "elements": [], + "elements_chain": "" + }, + { + "id": "1236f274-7cb4-4e63-9d19-18845e304a30", + "distinct_id": "01777279-ff1b-003e-70d7-fd45f1f1f43b", + "properties": { + "$current_url": "https://hogflix/profile" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:48.828797+00:00", + "person": "01777279-ff1b-003e-70d7-fd45f1f1f43b", + "elements": [], + "elements_chain": "" + }, + { + "id": "da806468-62d7-4d87-b5ea-a77659a9605e", + "distinct_id": "01777279-ff1b-003e-70d7-fd45f1f1f43b", + "properties": { + "$current_url": "https://hogflix/profile" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:56:03.828827+00:00", + "person": "01777279-ff1b-003e-70d7-fd45f1f1f43b", + "elements": [], + "elements_chain": "" + }, + { + "id": "e3dd769f-73af-45fb-bc39-760ac991dcda", + "distinct_id": "01777279-ff1b-003e-70d7-fd45f1f1f43b", + "properties": { + "app_rating": 3 + }, + "event": "rated_app", + "timestamp": "2021-02-04T13:56:18.828855+00:00", + "person": "01777279-ff1b-003e-70d7-fd45f1f1f43b", + "elements": [], + "elements_chain": "" + }, + { + "id": "d625409a-64e6-4887-8657-6083269d520d", + "distinct_id": "01777279-ff1b-003e-70d7-fd45f1f1f43b", + "properties": { + "is_first_movie": true + }, + "event": "watched_movie", + "timestamp": "2021-02-04T13:57:13.828767+00:00", + "person": "01777279-ff1b-003e-70d7-fd45f1f1f43b", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": null, + "session_recordings": [] + }, + { + "distinct_id": "01777279-ff1b-0037-1dac-4325a8e58e7e", + "global_session_id": 11, + "length": 100, + "start_time": "2021-02-04T13:55:33.827525Z", + "end_time": "2021-02-04T13:57:13.827565Z", + "event_count": 4, + "events": [ + { + "id": "a5cfd3a0-c4fc-41f2-8f10-4559b4e613dc", + "distinct_id": "01777279-ff1b-0037-1dac-4325a8e58e7e", + "properties": {}, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:33.827525+00:00", + "person": "01777279-ff1b-0037-1dac-4325a8e58e7e", + "elements": [], + "elements_chain": "" + }, + { + "id": "dd13bd2b-54f3-4eaf-b5e8-feb6d3020e34", + "distinct_id": "01777279-ff1b-0037-1dac-4325a8e58e7e", + "properties": {}, + "event": "installed_app", + "timestamp": "2021-02-04T13:55:33.827545+00:00", + "person": "01777279-ff1b-0037-1dac-4325a8e58e7e", + "elements": [], + "elements_chain": "" + }, + { + "id": "ddb1a1bc-b71e-42dc-abcd-627070d8b003", + "distinct_id": "01777279-ff1b-0037-1dac-4325a8e58e7e", + "properties": { + "$current_url": "https://hogflix/downloads" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:48.827598+00:00", + "person": "01777279-ff1b-0037-1dac-4325a8e58e7e", + "elements": [], + "elements_chain": "" + }, + { + "id": "800f1955-37b5-41fa-aa9a-3e11350d64ff", + "distinct_id": "01777279-ff1b-0037-1dac-4325a8e58e7e", + "properties": { + "is_first_movie": false + }, + "event": "watched_movie", + "timestamp": "2021-02-04T13:57:13.827565+00:00", + "person": "01777279-ff1b-0037-1dac-4325a8e58e7e", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": null, + "session_recordings": [] + }, + { + "distinct_id": "01777279-ff1b-0030-2685-ae9e52533421", + "global_session_id": 10, + "length": 100, + "start_time": "2021-02-04T13:55:33.826415Z", + "end_time": "2021-02-04T13:57:13.826452Z", + "event_count": 6, + "events": [ + { + "id": "a915f829-9e07-4a89-9de5-15b0193418a4", + "distinct_id": "01777279-ff1b-0030-2685-ae9e52533421", + "properties": {}, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:33.826415+00:00", + "person": "01777279-ff1b-0030-2685-ae9e52533421", + "elements": [], + "elements_chain": "" + }, + { + "id": "7abb2df7-b80b-4726-86ca-a1f502b9bcdb", + "distinct_id": "01777279-ff1b-0030-2685-ae9e52533421", + "properties": {}, + "event": "installed_app", + "timestamp": "2021-02-04T13:55:33.826433+00:00", + "person": "01777279-ff1b-0030-2685-ae9e52533421", + "elements": [], + "elements_chain": "" + }, + { + "id": "2089fde6-66cc-4aad-bdfa-1c2addf2995e", + "distinct_id": "01777279-ff1b-0030-2685-ae9e52533421", + "properties": { + "$current_url": "https://hogflix/movies" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:48.826482+00:00", + "person": "01777279-ff1b-0030-2685-ae9e52533421", + "elements": [], + "elements_chain": "" + }, + { + "id": "0ee2c625-f39c-4570-93d6-45ad6bd6230a", + "distinct_id": "01777279-ff1b-0030-2685-ae9e52533421", + "properties": { + "$current_url": "https://hogflix/settings" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:56:03.826513+00:00", + "person": "01777279-ff1b-0030-2685-ae9e52533421", + "elements": [], + "elements_chain": "" + }, + { + "id": "9c414a92-546f-4eb1-8fad-cedf460acdc0", + "distinct_id": "01777279-ff1b-0030-2685-ae9e52533421", + "properties": { + "app_rating": 4 + }, + "event": "rated_app", + "timestamp": "2021-02-04T13:56:18.826542+00:00", + "person": "01777279-ff1b-0030-2685-ae9e52533421", + "elements": [], + "elements_chain": "" + }, + { + "id": "c39d6e08-00bf-4461-91a9-da9a9efacfac", + "distinct_id": "01777279-ff1b-0030-2685-ae9e52533421", + "properties": { + "is_first_movie": false + }, + "event": "watched_movie", + "timestamp": "2021-02-04T13:57:13.826452+00:00", + "person": "01777279-ff1b-0030-2685-ae9e52533421", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": null, + "session_recordings": [] + }, + { + "distinct_id": "01777279-ff1b-002f-af76-94912ef0e236", + "global_session_id": 9, + "length": 100, + "start_time": "2021-02-04T13:55:33.826316Z", + "end_time": "2021-02-04T13:57:13.826353Z", + "event_count": 4, + "events": [ + { + "id": "0ca95c54-495c-463f-beb0-ddc515b8f23e", + "distinct_id": "01777279-ff1b-002f-af76-94912ef0e236", + "properties": {}, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:33.826316+00:00", + "person": "01777279-ff1b-002f-af76-94912ef0e236", + "elements": [], + "elements_chain": "" + }, + { + "id": "d0cc5ab5-1d45-42bc-805d-aa6608b39fd4", + "distinct_id": "01777279-ff1b-002f-af76-94912ef0e236", + "properties": {}, + "event": "installed_app", + "timestamp": "2021-02-04T13:55:33.826334+00:00", + "person": "01777279-ff1b-002f-af76-94912ef0e236", + "elements": [], + "elements_chain": "" + }, + { + "id": "bd82e952-41c5-402d-83c8-3bdf9165c05b", + "distinct_id": "01777279-ff1b-002f-af76-94912ef0e236", + "properties": { + "$current_url": "https://hogflix/movies" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:48.826383+00:00", + "person": "01777279-ff1b-002f-af76-94912ef0e236", + "elements": [], + "elements_chain": "" + }, + { + "id": "6064b192-a21a-4926-b8c2-8914da275b05", + "distinct_id": "01777279-ff1b-002f-af76-94912ef0e236", + "properties": { + "is_first_movie": false + }, + "event": "watched_movie", + "timestamp": "2021-02-04T13:57:13.826353+00:00", + "person": "01777279-ff1b-002f-af76-94912ef0e236", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": null, + "session_recordings": [] + }, + { + "distinct_id": "01777279-ff1b-000b-980e-815302415c4b", + "global_session_id": 8, + "length": 100, + "start_time": "2021-02-04T13:55:33.820705Z", + "end_time": "2021-02-04T13:57:13.820744Z", + "event_count": 6, + "events": [ + { + "id": "fcb860fe-0e4d-49fd-8e85-449667055ddc", + "distinct_id": "01777279-ff1b-000b-980e-815302415c4b", + "properties": {}, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:33.820705+00:00", + "person": "01777279-ff1b-000b-980e-815302415c4b", + "elements": [], + "elements_chain": "" + }, + { + "id": "1a737a13-72f3-4d22-9364-f1d639716d1e", + "distinct_id": "01777279-ff1b-000b-980e-815302415c4b", + "properties": {}, + "event": "installed_app", + "timestamp": "2021-02-04T13:55:33.820724+00:00", + "person": "01777279-ff1b-000b-980e-815302415c4b", + "elements": [], + "elements_chain": "" + }, + { + "id": "e533054e-c612-458e-a7e7-5439cb8b58ee", + "distinct_id": "01777279-ff1b-000b-980e-815302415c4b", + "properties": { + "$current_url": "https://hogflix/settings" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:48.820774+00:00", + "person": "01777279-ff1b-000b-980e-815302415c4b", + "elements": [], + "elements_chain": "" + }, + { + "id": "755549a9-3f8f-414c-9445-60528e840fa7", + "distinct_id": "01777279-ff1b-000b-980e-815302415c4b", + "properties": { + "$current_url": "https://hogflix/settings" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:56:03.820805+00:00", + "person": "01777279-ff1b-000b-980e-815302415c4b", + "elements": [], + "elements_chain": "" + }, + { + "id": "2855d20b-6c70-43c1-821a-4efb5ab3024a", + "distinct_id": "01777279-ff1b-000b-980e-815302415c4b", + "properties": { + "app_rating": 5 + }, + "event": "rated_app", + "timestamp": "2021-02-04T13:56:18.820835+00:00", + "person": "01777279-ff1b-000b-980e-815302415c4b", + "elements": [], + "elements_chain": "" + }, + { + "id": "c3c6e968-5681-4818-9ce6-525af40bd12a", + "distinct_id": "01777279-ff1b-000b-980e-815302415c4b", + "properties": { + "is_first_movie": false + }, + "event": "watched_movie", + "timestamp": "2021-02-04T13:57:13.820744+00:00", + "person": "01777279-ff1b-000b-980e-815302415c4b", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": null, + "session_recordings": [] + }, + { + "distinct_id": "01777279-ff1b-0009-7b14-6ed4c372c531", + "global_session_id": 7, + "length": 100, + "start_time": "2021-02-04T13:55:33.820438Z", + "end_time": "2021-02-04T13:57:13.820478Z", + "event_count": 4, + "events": [ + { + "id": "04069abe-e34f-454e-9e93-33c8940113df", + "distinct_id": "01777279-ff1b-0009-7b14-6ed4c372c531", + "properties": {}, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:33.820438+00:00", + "person": "01777279-ff1b-0009-7b14-6ed4c372c531", + "elements": [], + "elements_chain": "" + }, + { + "id": "caaaea75-2b6c-45bd-ac7b-a2e0b1129afb", + "distinct_id": "01777279-ff1b-0009-7b14-6ed4c372c531", + "properties": {}, + "event": "installed_app", + "timestamp": "2021-02-04T13:55:33.820458+00:00", + "person": "01777279-ff1b-0009-7b14-6ed4c372c531", + "elements": [], + "elements_chain": "" + }, + { + "id": "272079eb-4631-4594-8d52-b2bd9c7a5fa7", + "distinct_id": "01777279-ff1b-0009-7b14-6ed4c372c531", + "properties": { + "$current_url": "https://hogflix/movies" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:48.820509+00:00", + "person": "01777279-ff1b-0009-7b14-6ed4c372c531", + "elements": [], + "elements_chain": "" + }, + { + "id": "24cc492b-e931-43ff-8010-22b0cff3e4ed", + "distinct_id": "01777279-ff1b-0009-7b14-6ed4c372c531", + "properties": { + "is_first_movie": false + }, + "event": "watched_movie", + "timestamp": "2021-02-04T13:57:13.820478+00:00", + "person": "01777279-ff1b-0009-7b14-6ed4c372c531", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": null, + "session_recordings": [] + }, + { + "distinct_id": "01777279-f65b-0004-aed0-c825464180ef", + "global_session_id": 3, + "length": 30, + "start_time": "2021-02-04T13:55:31.579113Z", + "end_time": "2021-02-04T13:56:01.579206Z", + "event_count": 4, + "events": [ + { + "id": "403bd5e3-ea96-4ee9-ad0e-4ed349a3571b", + "distinct_id": "01777279-f65b-0004-aed0-c825464180ef", + "properties": { + "$current_url": "http://hogflix.com", + "$browser": "Chrome", + "$lib": "web" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:31.579113+00:00", + "person": "01777279-f65b-0004-aed0-c825464180ef", + "elements": [], + "elements_chain": "" + }, + { + "id": "2417a733-732a-48df-8809-2389ba463673", + "distinct_id": "01777279-f65b-0004-aed0-c825464180ef", + "properties": { + "$current_url": "http://hogflix.com", + "$browser": "Chrome", + "$lib": "web", + "$event_type": "click" + }, + "event": "$autocapture", + "timestamp": "2021-02-04T13:55:45.579137+00:00", + "person": "01777279-f65b-0004-aed0-c825464180ef", + "elements": [], + "elements_chain": "" + }, + { + "id": "705a0937-3e36-4441-9efb-52f41fcde031", + "distinct_id": "01777279-f65b-0004-aed0-c825464180ef", + "properties": { + "$current_url": "http://hogflix.com/1", + "$browser": "Chrome", + "$lib": "web", + "$event_type": "click" + }, + "event": "$autocapture", + "timestamp": "2021-02-04T13:56:00.579172+00:00", + "person": "01777279-f65b-0004-aed0-c825464180ef", + "elements": [], + "elements_chain": "" + }, + { + "id": "8a8f42ec-4c03-4f5d-bac5-1ab3c218da75", + "distinct_id": "01777279-f65b-0004-aed0-c825464180ef", + "properties": { + "$current_url": "http://hogflix.com/2", + "$browser": "Chrome", + "$lib": "web" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:56:01.579206+00:00", + "person": "01777279-f65b-0004-aed0-c825464180ef", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": "hodge.espinoza@cubix.io", + "session_recordings": [] + }, + { + "distinct_id": "01777279-f65b-000f-53e8-01abaa5b1d86", + "global_session_id": 6, + "length": 14, + "start_time": "2021-02-04T13:55:31.580601Z", + "end_time": "2021-02-04T13:55:45.580629Z", + "event_count": 2, + "events": [ + { + "id": "7f2dd92d-1f52-4dfc-afa0-a3072e3b0258", + "distinct_id": "01777279-f65b-000f-53e8-01abaa5b1d86", + "properties": { + "$current_url": "http://hogflix.com", + "$browser": "Firefox", + "$lib": "web" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:31.580601+00:00", + "person": "01777279-f65b-000f-53e8-01abaa5b1d86", + "elements": [], + "elements_chain": "" + }, + { + "id": "85c59877-3c24-4146-8921-f642948cb492", + "distinct_id": "01777279-f65b-000f-53e8-01abaa5b1d86", + "properties": { + "$current_url": "http://hogflix.com", + "$browser": "Firefox", + "$lib": "web", + "$event_type": "click" + }, + "event": "$autocapture", + "timestamp": "2021-02-04T13:55:45.580629+00:00", + "person": "01777279-f65b-000f-53e8-01abaa5b1d86", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": "suzanne.mitchell@gmail.com", + "session_recordings": [] + }, + { + "distinct_id": "01777279-f65b-000d-8945-d7cea8f0f63b", + "global_session_id": 5, + "length": 14, + "start_time": "2021-02-04T13:55:31.580446Z", + "end_time": "2021-02-04T13:55:45.580496Z", + "event_count": 2, + "events": [ + { + "id": "15ef148f-faab-425a-b76c-c854adac3e71", + "distinct_id": "01777279-f65b-000d-8945-d7cea8f0f63b", + "properties": { + "$current_url": "http://hogflix.com", + "$browser": "Chrome", + "$lib": "web" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:31.580446+00:00", + "person": "01777279-f65b-000d-8945-d7cea8f0f63b", + "elements": [], + "elements_chain": "" + }, + { + "id": "0bb2395c-889a-454a-8f4f-e41a211b8d8a", + "distinct_id": "01777279-f65b-000d-8945-d7cea8f0f63b", + "properties": { + "$current_url": "http://hogflix.com", + "$browser": "Chrome", + "$lib": "web", + "$event_type": "click" + }, + "event": "$autocapture", + "timestamp": "2021-02-04T13:55:45.580496+00:00", + "person": "01777279-f65b-000d-8945-d7cea8f0f63b", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": "tara.roth@hotmail.com", + "session_recordings": [] + }, + { + "distinct_id": "01777279-f65b-0009-a1f3-8d3f02ee499a", + "global_session_id": 4, + "length": 14, + "start_time": "2021-02-04T13:55:31.579976Z", + "end_time": "2021-02-04T13:55:45.580003Z", + "event_count": 2, + "events": [ + { + "id": "7057dd43-634c-41a9-adbd-68687ba2c88a", + "distinct_id": "01777279-f65b-0009-a1f3-8d3f02ee499a", + "properties": { + "$current_url": "http://hogflix.com", + "$browser": "Safari", + "$lib": "web" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:31.579976+00:00", + "person": "01777279-f65b-0009-a1f3-8d3f02ee499a", + "elements": [], + "elements_chain": "" + }, + { + "id": "dee7e72b-8061-4ca7-bfee-6475d2d5c770", + "distinct_id": "01777279-f65b-0009-a1f3-8d3f02ee499a", + "properties": { + "$current_url": "http://hogflix.com", + "$browser": "Safari", + "$lib": "web", + "$event_type": "click" + }, + "event": "$autocapture", + "timestamp": "2021-02-04T13:55:45.580003+00:00", + "person": "01777279-f65b-0009-a1f3-8d3f02ee499a", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": "sybil.huber@gmail.com", + "session_recordings": [] + }, + { + "distinct_id": "01777279-f65a-001e-f914-f106864d9332", + "global_session_id": 2, + "length": 14, + "start_time": "2021-02-04T13:55:31.578682Z", + "end_time": "2021-02-04T13:55:45.578705Z", + "event_count": 2, + "events": [ + { + "id": "ee7f83dc-eeed-4156-a156-7e819d103ec7", + "distinct_id": "01777279-f65a-001e-f914-f106864d9332", + "properties": { + "$current_url": "http://hogflix.com", + "$browser": "Safari", + "$lib": "web" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:31.578682+00:00", + "person": "01777279-f65a-001e-f914-f106864d9332", + "elements": [], + "elements_chain": "" + }, + { + "id": "9b278d87-222b-49ad-94b3-9b4569efd726", + "distinct_id": "01777279-f65a-001e-f914-f106864d9332", + "properties": { + "$current_url": "http://hogflix.com", + "$browser": "Safari", + "$lib": "web", + "$event_type": "click" + }, + "event": "$autocapture", + "timestamp": "2021-02-04T13:55:45.578705+00:00", + "person": "01777279-f65a-001e-f914-f106864d9332", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": "palmer.goodman@hotmail.com", + "session_recordings": [] + }, + { + "distinct_id": "01777279-f65a-0019-3076-d99ce1215ba4", + "global_session_id": 1, + "length": 14, + "start_time": "2021-02-04T13:55:31.578310Z", + "end_time": "2021-02-04T13:55:45.578337Z", + "event_count": 2, + "events": [ + { + "id": "1820513f-3be9-4a8f-9341-65b55ebab72d", + "distinct_id": "01777279-f65a-0019-3076-d99ce1215ba4", + "properties": { + "$current_url": "http://hogflix.com", + "$browser": "Firefox", + "$lib": "web" + }, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:31.578310+00:00", + "person": "01777279-f65a-0019-3076-d99ce1215ba4", + "elements": [], + "elements_chain": "" + }, + { + "id": "78979184-3c25-42dd-9aed-3399bdca1bbc", + "distinct_id": "01777279-f65a-0019-3076-d99ce1215ba4", + "properties": { + "$current_url": "http://hogflix.com", + "$browser": "Firefox", + "$lib": "web", + "$event_type": "click" + }, + "event": "$autocapture", + "timestamp": "2021-02-04T13:55:45.578337+00:00", + "person": "01777279-f65a-0019-3076-d99ce1215ba4", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": "bettie.stone@gmail.com", + "session_recordings": [] + }, + { + "distinct_id": "0177727a-19eb-001f-0fa4-8e87aa6a1d5b", + "global_session_id": 15, + "length": 0, + "start_time": "2021-02-04T13:55:40.674044Z", + "end_time": "2021-02-04T13:55:40.674063Z", + "event_count": 2, + "events": [ + { + "id": "de245db1-2e4c-49a2-a4fa-59afc5ffe228", + "distinct_id": "0177727a-19eb-001f-0fa4-8e87aa6a1d5b", + "properties": {}, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:40.674044+00:00", + "person": "0177727a-19eb-001f-0fa4-8e87aa6a1d5b", + "elements": [], + "elements_chain": "" + }, + { + "id": "c3166d5d-bb8d-4efd-8a19-38ea6f66a70c", + "distinct_id": "0177727a-19eb-001f-0fa4-8e87aa6a1d5b", + "properties": { + "plan": "standard", + "purchase_value": 13 + }, + "event": "purchase", + "timestamp": "2021-02-04T13:55:40.674063+00:00", + "person": "0177727a-19eb-001f-0fa4-8e87aa6a1d5b", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": null, + "session_recordings": [] + }, + { + "distinct_id": "01777279-ff1b-0066-5989-fb1cd49dfc84", + "global_session_id": 14, + "length": 0, + "start_time": "2021-02-04T13:55:33.834478Z", + "end_time": "2021-02-04T13:55:33.834496Z", + "event_count": 2, + "events": [ + { + "id": "03e367a2-bd1b-46e2-93c6-accdc29d3212", + "distinct_id": "01777279-ff1b-0066-5989-fb1cd49dfc84", + "properties": {}, + "event": "$pageview", + "timestamp": "2021-02-04T13:55:33.834478+00:00", + "person": "01777279-ff1b-0066-5989-fb1cd49dfc84", + "elements": [], + "elements_chain": "" + }, + { + "id": "fe2192c4-14d9-4028-ad92-5c6a9b295153", + "distinct_id": "01777279-ff1b-0066-5989-fb1cd49dfc84", + "properties": {}, + "event": "installed_app", + "timestamp": "2021-02-04T13:55:33.834496+00:00", + "person": "01777279-ff1b-0066-5989-fb1cd49dfc84", + "elements": [], + "elements_chain": "" + } + ], + "properties": {}, + "matching_events": [], + "email": null, + "session_recordings": [] + } + ], + "pagination": { + "offset": 10 + } +} diff --git a/cypress/fixtures/api/person/properties.json b/cypress/fixtures/api/person/properties.json new file mode 100644 index 00000000000..f2114ebfe0f --- /dev/null +++ b/cypress/fixtures/api/person/properties.json @@ -0,0 +1,12 @@ +[ + { "name": "is_demo", "count": 160 }, + { "name": "email", "count": 36 }, + { "name": "address", "count": 35 }, + { "name": "name", "count": 35 }, + { "name": "phone", "count": 35 }, + { "name": "$browser", "count": 1 }, + { "name": "$browser_version", "count": 1 }, + { "name": "$initial_referrer", "count": 1 }, + { "name": "$initial_referring_domain", "count": 1 }, + { "name": "$os", "count": 1 } +] diff --git a/cypress/fixtures/api/personal_api_keys.json b/cypress/fixtures/api/personal_api_keys.json new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cypress/fixtures/api/personal_api_keys.json @@ -0,0 +1 @@ +[] diff --git a/cypress/fixtures/api/projects/@current.json b/cypress/fixtures/api/projects/@current.json new file mode 100644 index 00000000000..26ffff38271 --- /dev/null +++ b/cypress/fixtures/api/projects/@current.json @@ -0,0 +1,118 @@ +{ + "id": 2, + "organization": "01777279-f5a2-0000-b1d5-dbfc148b9426", + "api_token": "JqcIEQVjX-CxbPiittsio2ZTIB2pHUBmGVGgQE4Io0I", + "app_urls": [], + "name": "HogFlix Demo App", + "slack_incoming_webhook": null, + "event_names": [ + "watched_movie", + "installed_app", + "rated_app", + "purchase", + "entered_free_trial", + "$identify", + "$pageview", + "$autocapture", + "personalization skipped", + "insight viewed", + "$pageleave", + "$capture_metrics" + ], + "event_properties": [ + "$current_url", + "is_first_movie", + "plan", + "first_visit", + "$set", + "$ip", + "$os", + "$browser", + "$host", + "$pathname", + "$browser_version", + "$screen_height", + "$screen_width", + "$lib", + "$lib_version", + "$insert_id", + "$time", + "distinct_id", + "$device_id", + "$initial_referrer", + "$initial_referring_domain", + "$referrer", + "$referring_domain", + "$active_feature_flags", + "$user_id", + "$anon_distinct_id", + "token", + "posthog_version", + "has_slack_webhook", + "$event_type", + "$ce_version", + "is_first_component_load", + "insight", + "display", + "interval", + "filters", + "filters_count", + "events_count", + "actions_count", + "total_event_actions_count", + "phjs-_send_request", + "phjs-_send_request_inflight", + "phjs-capture", + "phjs-batch-enqueue", + "phjs-xhr-response", + "phjs-xhr-response-200", + "phjs-identify", + "phjs-batch-requests", + "phjs-batch-requests-e/", + "phjs-batch-handle", + "phjs-batch-handle-e/", + "phjs-batch-unload-requests", + "phjs-batch-unload-requests-e/", + "phjs-batch-unload", + "phjs-batch-unload-e/" + ], + "event_properties_numerical": [ + "purchase", + "app_rating", + "purchase_value", + "$browser_version", + "$screen_height", + "$screen_width", + "$time", + "has_slack_webhook", + "$ce_version", + "is_first_component_load", + "filters_count", + "events_count", + "actions_count", + "total_event_actions_count", + "phjs-_send_request", + "phjs-_send_request_inflight", + "phjs-capture", + "phjs-batch-enqueue", + "phjs-xhr-response", + "phjs-xhr-response-200", + "phjs-identify", + "phjs-batch-requests", + "phjs-batch-requests-e/", + "phjs-batch-handle", + "phjs-batch-handle-e/", + "phjs-batch-unload-requests", + "phjs-batch-unload-requests-e/", + "phjs-batch-unload", + "phjs-batch-unload-e/" + ], + "created_at": "2021-02-05T13:55:31.489580Z", + "updated_at": "2021-02-05T13:55:52.852345Z", + "anonymize_ips": false, + "completed_snippet_onboarding": true, + "ingested_event": true, + "uuid": "01777279-f621-0000-1c87-13657da18040", + "opt_out_capture": false, + "is_demo": true +} diff --git a/cypress/fixtures/api/sessions_filter.json b/cypress/fixtures/api/sessions_filter.json new file mode 100644 index 00000000000..adc81bb4c88 --- /dev/null +++ b/cypress/fixtures/api/sessions_filter.json @@ -0,0 +1,24 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "name": "ChromeUsers", + "created_by": { + "id": 2, + "distinct_id": "NFuDfZu5XKan7pDu3wCbvjJbVsoejlG6O6D8VaN96vA", + "first_name": "Karl", + "email": "karl@posthog.com" + }, + "created_at": "2021-02-08T08:43:40.744073Z", + "updated_at": "2021-02-08T08:43:40.744112Z", + "filters": { + "properties": [ + { "key": "$browser", "type": "person", "label": "$browser", "value": "Chrome", "operator": "exact" } + ] + } + } + ] +} diff --git a/cypress/fixtures/api/user.json b/cypress/fixtures/api/user.json new file mode 100644 index 00000000000..10d6b740c38 --- /dev/null +++ b/cypress/fixtures/api/user.json @@ -0,0 +1,460 @@ +{ + "id": 2, + "distinct_id": "NFuDfZu5XKan7pDu3wCbvjJbVsoejlG6O6D8VaN96vA", + "name": "TestUser", + "email": "test@posthog.com", + "email_opt_in": true, + "anonymize_data": false, + "toolbar_mode": "toolbar", + "organization": { + "id": "01777279-f5a2-0000-b1d5-dbfc148b9426", + "name": "Foo", + "billing_plan": null, + "available_features": [], + "created_at": "2021-02-05T13:55:31.362Z", + "updated_at": "2021-02-05T13:55:44.244Z", + "teams": [ + { + "id": 2, + "name": "HogFlix Demo App" + } + ] + }, + "organizations": [ + { + "name": "Foo", + "id": "01777279-f5a2-0000-b1d5-dbfc148b9426" + } + ], + "team": { + "id": 2, + "name": "HogFlix Demo App", + "app_urls": [], + "api_token": "JqcIEQVjX-CxbPiittsio2ZTIB2pHUBmGVGgQE4Io0I", + "opt_out_capture": false, + "anonymize_ips": false, + "slack_incoming_webhook": null, + "event_names": [ + "watched_movie", + "installed_app", + "rated_app", + "purchase", + "entered_free_trial", + "$identify", + "$pageview", + "$autocapture", + "personalization skipped", + "insight viewed", + "$pageleave", + "$capture_metrics" + ], + "event_names_with_usage": [ + { + "event": "$identify", + "volume": null, + "usage_count": null + }, + { + "event": "$pageview", + "volume": null, + "usage_count": null + }, + { + "event": "$autocapture", + "volume": null, + "usage_count": null + }, + { + "event": "personalization skipped", + "volume": null, + "usage_count": null + }, + { + "event": "insight viewed", + "volume": null, + "usage_count": null + }, + { + "event": "$pageleave", + "volume": null, + "usage_count": null + }, + { + "event": "$capture_metrics", + "volume": null, + "usage_count": null + } + ], + "event_properties": [ + "$current_url", + "is_first_movie", + "plan", + "first_visit", + "$set", + "$ip", + "$os", + "$browser", + "$host", + "$pathname", + "$browser_version", + "$screen_height", + "$screen_width", + "$lib", + "$lib_version", + "$insert_id", + "$time", + "distinct_id", + "$device_id", + "$initial_referrer", + "$initial_referring_domain", + "$referrer", + "$referring_domain", + "$active_feature_flags", + "$user_id", + "$anon_distinct_id", + "token", + "posthog_version", + "has_slack_webhook", + "$event_type", + "$ce_version", + "is_first_component_load", + "insight", + "display", + "interval", + "filters", + "filters_count", + "events_count", + "actions_count", + "total_event_actions_count", + "phjs-_send_request", + "phjs-_send_request_inflight", + "phjs-capture", + "phjs-batch-enqueue", + "phjs-xhr-response", + "phjs-xhr-response-200", + "phjs-identify", + "phjs-batch-requests", + "phjs-batch-requests-e/", + "phjs-batch-handle", + "phjs-batch-handle-e/", + "phjs-batch-unload-requests", + "phjs-batch-unload-requests-e/", + "phjs-batch-unload", + "phjs-batch-unload-e/" + ], + "event_properties_numerical": [ + "purchase", + "app_rating", + "purchase_value", + "$browser_version", + "$screen_height", + "$screen_width", + "$time", + "has_slack_webhook", + "$ce_version", + "is_first_component_load", + "filters_count", + "events_count", + "actions_count", + "total_event_actions_count", + "phjs-_send_request", + "phjs-_send_request_inflight", + "phjs-capture", + "phjs-batch-enqueue", + "phjs-xhr-response", + "phjs-xhr-response-200", + "phjs-identify", + "phjs-batch-requests", + "phjs-batch-requests-e/", + "phjs-batch-handle", + "phjs-batch-handle-e/", + "phjs-batch-unload-requests", + "phjs-batch-unload-requests-e/", + "phjs-batch-unload", + "phjs-batch-unload-e/" + ], + "event_properties_with_usage": [ + { + "key": "$set", + "volume": null, + "usage_count": null + }, + { + "key": "$ip", + "volume": null, + "usage_count": null + }, + { + "key": "$os", + "volume": null, + "usage_count": null + }, + { + "key": "$browser", + "volume": null, + "usage_count": null + }, + { + "key": "$host", + "volume": null, + "usage_count": null + }, + { + "key": "$pathname", + "volume": null, + "usage_count": null + }, + { + "key": "$browser_version", + "volume": null, + "usage_count": null + }, + { + "key": "$screen_height", + "volume": null, + "usage_count": null + }, + { + "key": "$screen_width", + "volume": null, + "usage_count": null + }, + { + "key": "$lib", + "volume": null, + "usage_count": null + }, + { + "key": "$lib_version", + "volume": null, + "usage_count": null + }, + { + "key": "$insert_id", + "volume": null, + "usage_count": null + }, + { + "key": "$time", + "volume": null, + "usage_count": null + }, + { + "key": "distinct_id", + "volume": null, + "usage_count": null + }, + { + "key": "$device_id", + "volume": null, + "usage_count": null + }, + { + "key": "$initial_referrer", + "volume": null, + "usage_count": null + }, + { + "key": "$initial_referring_domain", + "volume": null, + "usage_count": null + }, + { + "key": "$referrer", + "volume": null, + "usage_count": null + }, + { + "key": "$referring_domain", + "volume": null, + "usage_count": null + }, + { + "key": "$active_feature_flags", + "volume": null, + "usage_count": null + }, + { + "key": "$user_id", + "volume": null, + "usage_count": null + }, + { + "key": "$anon_distinct_id", + "volume": null, + "usage_count": null + }, + { + "key": "token", + "volume": null, + "usage_count": null + }, + { + "key": "posthog_version", + "volume": null, + "usage_count": null + }, + { + "key": "has_slack_webhook", + "volume": null, + "usage_count": null + }, + { + "key": "$event_type", + "volume": null, + "usage_count": null + }, + { + "key": "$ce_version", + "volume": null, + "usage_count": null + }, + { + "key": "is_first_component_load", + "volume": null, + "usage_count": null + }, + { + "key": "insight", + "volume": null, + "usage_count": null + }, + { + "key": "display", + "volume": null, + "usage_count": null + }, + { + "key": "interval", + "volume": null, + "usage_count": null + }, + { + "key": "filters", + "volume": null, + "usage_count": null + }, + { + "key": "filters_count", + "volume": null, + "usage_count": null + }, + { + "key": "events_count", + "volume": null, + "usage_count": null + }, + { + "key": "actions_count", + "volume": null, + "usage_count": null + }, + { + "key": "total_event_actions_count", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-_send_request", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-_send_request_inflight", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-capture", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-batch-enqueue", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-xhr-response", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-xhr-response-200", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-identify", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-batch-requests", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-batch-requests-e/", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-batch-handle", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-batch-handle-e/", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-batch-unload-requests", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-batch-unload-requests-e/", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-batch-unload", + "volume": null, + "usage_count": null + }, + { + "key": "phjs-batch-unload-e/", + "volume": null, + "usage_count": null + } + ], + "completed_snippet_onboarding": true, + "session_recording_opt_in": false, + "session_recording_retention_period_days": null, + "plugins_opt_in": false, + "ingested_event": true, + "is_demo": true + }, + "teams": [ + { + "name": "HogFlix Demo App", + "id": 2 + } + ], + "has_password": true, + "opt_out_capture": null, + "posthog_version": "1.20.0", + "is_multi_tenancy": false, + "ee_available": true, + "ee_enabled": true, + "email_service_available": false, + "is_debug": true, + "is_staff": false, + "is_impersonated": false, + "plugin_access": { + "install": true, + "configure": true + } +} diff --git a/cypress/integration/person.js b/cypress/integration/person.js index 15cb6f3c1bb..6c303f244d3 100644 --- a/cypress/integration/person.js +++ b/cypress/integration/person.js @@ -1,7 +1,7 @@ describe('Person Visualization Check', () => { beforeEach(() => { cy.get('[data-attr=menu-item-persons]').click() - cy.get('.ant-spin-spinning').should('not.visible') // Wait until initial table load to be able to use the search + cy.get('.ant-spin-spinning').should('not.exist') // Wait until initial table load to be able to use the search cy.get('[data-attr=persons-search]').type('deb').should('have.value', 'deb') cy.get('.ant-input-search-button').click() cy.contains('deborah.fernandez@gmail.com').click() @@ -22,7 +22,7 @@ describe('Person Visualization Check', () => { describe('Person Show All Distinct Checks', () => { beforeEach(() => { cy.get('[data-attr=menu-item-persons]').click() - cy.get('.ant-spin-spinning').should('not.visible') // Wait until initial table load + cy.get('.ant-spin-spinning').should('not.exist') // Wait until initial table load }) it('Should have no Show All Distinct Id Button', () => { diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js index 116b9829a56..dd76b0547ac 100644 --- a/cypress/plugins/index.js +++ b/cypress/plugins/index.js @@ -1,4 +1,18 @@ -module.exports = (on) => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - require('cypress-terminal-report/src/installLogsPrinter')(on) +const webpackPreprocessor = require('@cypress/webpack-preprocessor') + +const { createEntry } = require('../../webpack.config') + +module.exports = (on, config) => { + const options = { + webpackOptions: createEntry('cypress'), + watchOptions: {}, + } + + on('file:preprocessor', webpackPreprocessor(options)) + try { + // eslint-disable-next-line @typescript-eslint/no-var-requires + require('cypress-terminal-report/src/installLogsPrinter')(on) + } catch (e) {} + + return config } diff --git a/cypress/support/commands.js b/cypress/support/commands.js index e69de29bb2d..3c0bad82af5 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -0,0 +1,9 @@ +Cypress.Commands.add('interceptLazy', (pattern, handler) => { + return cy.intercept(pattern, (req) => { + req.reply(handler()) + }) +}) + +Cypress.Commands.add('map', { prevSubject: true }, (subject, method) => { + return method(subject) +}) diff --git a/cypress/support/helpers.js b/cypress/support/helpers.js new file mode 100644 index 00000000000..8f49f571a14 --- /dev/null +++ b/cypress/support/helpers.js @@ -0,0 +1,39 @@ +import React from 'react' + +import { mount } from '@cypress/react' +import { Provider } from 'react-redux' +import { getContext } from 'kea' +import { initKea } from '~/initKea' +import { GlobalStyles } from '~/GlobalStyles' +import posthog from 'posthog-js' + +export const mountPage = (component) => { + initKea() + return mount( + + + {component} + + ) +} + +export const setLocation = (path) => { + window.history.replaceState(null, '', path) +} + +export const getSearchParameters = ({ request }) => { + const searchParams = new URL(request.url).searchParams + const result = {} + for (const [key, value] of searchParams.entries()) { + result[key] = value + } + return result +} + +export const mockPosthog = () => { + cy.stub(posthog) + posthog.people = { set: () => {} } + posthog.onFeatureFlags = (callback) => { + callback(given.featureFlags || []) + } +} diff --git a/cypress/support/index.js b/cypress/support/index.js index 95e397a3e9b..8f2de04e657 100644 --- a/cypress/support/index.js +++ b/cypress/support/index.js @@ -1,16 +1,33 @@ +import '@cypress/react/support' +import 'givens/setup' import './commands' -// eslint-disable-next-line @typescript-eslint/no-var-requires -require('cypress-terminal-report/src/installLogsCollector')() +import { unmount } from '@cypress/react' + +try { + // eslint-disable-next-line @typescript-eslint/no-var-requires + require('cypress-terminal-report/src/installLogsCollector')() +} catch {} beforeEach(() => { - cy.visit('/') + if (Cypress.spec.specType === 'component') { + // Freeze time to 2021.01.05 Noon UTC - this should be the same date regardless of timezone. + cy.clock(1578225600000, ['Date']) + } else { + cy.visit('/') - cy.url().then((url) => { - if (url.includes('login')) { - logIn() - } - }) + cy.url().then((url) => { + if (url.includes('login')) { + logIn() + } + }) + } +}) + +afterEach(() => { + if (Cypress.spec.specType === 'component') { + unmount() + } }) const logIn = () => { diff --git a/frontend/src/GlobalStyles.tsx b/frontend/src/GlobalStyles.tsx new file mode 100644 index 00000000000..e97542ca28e --- /dev/null +++ b/frontend/src/GlobalStyles.tsx @@ -0,0 +1,7 @@ +import '~/global.scss' /* Contains PostHog's main styling configurations */ +import '~/antd.less' /* Imports Ant Design's components */ +import './style.scss' /* DEPRECATED */ + +export function GlobalStyles(): null { + return null +} diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 98e0b30705e..53e016c1df3 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,6 +1,3 @@ -import '~/global.scss' /* Contains PostHog's main styling configurations */ -import '~/antd.less' /* Imports Ant Design's components */ -import './style.scss' /* DEPRECATED */ import React from 'react' import ReactDOM from 'react-dom' import { Provider } from 'react-redux' @@ -10,12 +7,14 @@ import { App } from 'scenes/App' import { initKea } from './initKea' import { loadPostHogJS } from './loadPostHogJS' +import { GlobalStyles } from './GlobalStyles' loadPostHogJS() initKea() ReactDOM.render( + , document.getElementById('root') diff --git a/frontend/src/lib/utils.test.js b/frontend/src/lib/utils.test.js index f978fc736f9..ea2b05f72a6 100644 --- a/frontend/src/lib/utils.test.js +++ b/frontend/src/lib/utils.test.js @@ -32,22 +32,28 @@ describe('formatLabel()', () => { expect(given.subject).toEqual('some_event (Total) ') }) - it('handles DAU queries', () => { + describe('DAU queries', () => { given('action', () => ({ math: 'dau' })) - expect(given.subject).toEqual('some_event (DAU) ') + it('is formatted', () => { + expect(given.subject).toEqual('some_event (DAU) ') + }) }) - it('handles summing by property', () => { + describe('summing by property', () => { given('action', () => ({ math: 'sum', math_property: 'event_property' })) - expect(given.subject).toEqual('some_event (sum of event_property) ') + it('is formatted', () => { + expect(given.subject).toEqual('some_event (sum of event_property) ') + }) }) - it('handles action with properties', () => { + describe('action with properties', () => { given('action', () => ({ properties: [{ value: 'hello' }, { operator: 'gt', value: 5 }] })) - expect(given.subject).toEqual('some_event (Total) (= hello, > 5)') + it('is formatted', () => { + expect(given.subject).toEqual('some_event (Total) (= hello, > 5)') + }) }) }) diff --git a/frontend/src/scenes/events/createActionFromEvent.test.js b/frontend/src/scenes/events/createActionFromEvent.test.js index 0b9b8ca5e25..d44ed1d57b9 100644 --- a/frontend/src/scenes/events/createActionFromEvent.test.js +++ b/frontend/src/scenes/events/createActionFromEvent.test.js @@ -51,47 +51,53 @@ describe('createActionFromEvent()', () => { expect(toast.mock.calls).toMatchSnapshot() }) - it('handles increments', async () => { + describe('increments', () => { given('increment', () => 4) - await given.subject() + it('handles increments', async () => { + await given.subject() - expect(api.create).toHaveBeenCalledWith('api/action', { - name: 'some-event event 4', - steps: [{ event: 'some-event', url: 'http://foo.bar/some/path', url_matching: 'exact' }], + expect(api.create).toHaveBeenCalledWith('api/action', { + name: 'some-event event 4', + steps: [{ event: 'some-event', url: 'http://foo.bar/some/path', url_matching: 'exact' }], + }) }) }) - it('handles submit $autocapture events with elements', async () => { + describe('$autocapture events', () => { given('eventName', () => '$autocapture') given('eventType', () => 'submit') given('elements', () => [{ tag_name: 'form', text: 'Submit form!' }, {}]) - await given.subject() + it('handles submit $autocapture events with elements', async () => { + await given.subject() - expect(api.create).toHaveBeenCalledWith('api/action', { - name: 'submitted form with text "Submit form!"', - steps: [ - { - event: '$autocapture', - url: 'http://foo.bar/some/path', - url_matching: 'exact', - tag_name: 'form', - text: 'Submit form!', - properties: [{ key: '$event_type', value: 'submit' }], - }, - ], + expect(api.create).toHaveBeenCalledWith('api/action', { + name: 'submitted form with text "Submit form!"', + steps: [ + { + event: '$autocapture', + url: 'http://foo.bar/some/path', + url_matching: 'exact', + tag_name: 'form', + text: 'Submit form!', + properties: [{ key: '$event_type', value: 'submit' }], + }, + ], + }) }) }) - it('handles $pageview events', async () => { + describe('$pageview event', () => { given('eventName', () => '$pageview') - await given.subject() + it('is handled', async () => { + await given.subject() - expect(api.create).toHaveBeenCalledWith('api/action', { - name: 'Pageview on /some/path', - steps: [{ event: '$pageview', url: 'http://foo.bar/some/path', url_matching: 'exact' }], + expect(api.create).toHaveBeenCalledWith('api/action', { + name: 'Pageview on /some/path', + steps: [{ event: '$pageview', url: 'http://foo.bar/some/path', url_matching: 'exact' }], + }) }) }) }) @@ -110,13 +116,15 @@ describe('createActionFromEvent()', () => { expect(toast).not.toHaveBeenCalled() }) - it('stops recursion if increment == 30', async () => { + describe('increment == 30', () => { given('increment', () => 30) - await given.subject() + it('stops recursion', async () => { + await given.subject() - expect(given.recurse).not.toHaveBeenCalled() - expect(toast).not.toHaveBeenCalled() + expect(given.recurse).not.toHaveBeenCalled() + expect(toast).not.toHaveBeenCalled() + }) }) }) }) diff --git a/frontend/src/scenes/sessions/Sessions.cy-spec.js b/frontend/src/scenes/sessions/Sessions.cy-spec.js new file mode 100644 index 00000000000..5210b444c08 --- /dev/null +++ b/frontend/src/scenes/sessions/Sessions.cy-spec.js @@ -0,0 +1,94 @@ +import React from 'react' +import { Sessions } from './Sessions' +import * as helpers from 'cypress/support/helpers' + +describe('', () => { + const mount = () => helpers.mountPage() + + beforeEach(() => { + cy.intercept('/api/user/', { fixture: 'api/user' }) + cy.intercept('/api/dashboard/', { fixture: 'api/dashboard' }) + cy.intercept('/api/personal_api_keys/', { fixture: 'api/personal_api_keys' }) + cy.intercept('/api/projects/@current/', { fixture: 'api/projects/@current' }) + cy.intercept('/api/person/properties/', { fixture: 'api/person/properties' }) + cy.interceptLazy('/api/event/sessions/', () => given.sessions).as('api_sessions') + + helpers.mockPosthog() + helpers.setLocation('/sessions') + }) + + given('featureFlags', () => ['filter_by_session_props']) + given('sessions', () => ({ fixture: 'api/event/sessions/demo_sessions' })) + + it('can navigate within sessions page', () => { + mount() + + cy.contains('Sessions').should('be.visible') + cy.wait('@api_sessions').map(helpers.getSearchParameters).should('include', { + date_from: '2020-01-05', + date_to: '2020-01-05', + distinct_id: '', + filters: '[]', + offset: '0', + properties: '[]', + }) + + cy.log('Play all disabled') + cy.get('[data-attr="play-all-recordings"]').should('have.attr', 'disabled') + + cy.log('Load more should work') + cy.get('[data-attr="load-more-sessions"]').click() + cy.wait('@api_sessions') + .map(helpers.getSearchParameters) + .should('include', { + date_from: '2020-01-05', + date_to: '2020-01-05', + pagination: JSON.stringify({ offset: 10 }), + }) + + cy.get('[data-attr="sessions-prev-date"]').click() + cy.wait('@api_sessions').map(helpers.getSearchParameters).should('include', { + date_from: '2020-01-04', + date_to: '2020-01-04', + }) + }) + + it('can filter sessions', () => { + mount() + cy.wait('@api_sessions') + + cy.get('[data-attr="sessions-filter-open"]').click() + cy.focused().type('br').type('{downarrow}').type('{enter}') + cy.get('.sessions-filter-row input').last().type('Chrome').type('{enter}') + + cy.contains('There are unapplied filters').should('be.visible') + cy.get('[data-attr="sessions-apply-filters"]').click() + cy.contains('There are unapplied filters').should('not.exist') + + cy.wait('@api_sessions').map(helpers.getSearchParameters).should('include', { + filters: '[{"type":"person","key":"$browser","value":"Chrome","label":"$browser","operator":"exact"}]', + }) + }) + + describe('sessions filters', () => { + beforeEach(() => { + cy.intercept('/api/sessions_filter/', { fixture: 'api/sessions_filter' }).as('sessions_filter') + }) + + it('renders sessions filters', () => { + mount() + cy.wait('@api_sessions') + cy.wait('@sessions_filter') + + cy.contains('Unseen recordings').should('be.visible') + cy.contains('ChromeUsers').should('be.visible') + + cy.get('[data-attr="sessions-filter-link"]').last().click() + + cy.wait('@api_sessions') + cy.get('@api_sessions').map(helpers.getSearchParameters).should('include', { + filters: '[{"key":"$browser","type":"person","label":"$browser","value":"Chrome","operator":"exact"}]', + }) + }) + }) +}) diff --git a/frontend/src/scenes/sessions/SessionsView.tsx b/frontend/src/scenes/sessions/SessionsView.tsx index 36f65862535..7a9f0f4d5b5 100644 --- a/frontend/src/scenes/sessions/SessionsView.tsx +++ b/frontend/src/scenes/sessions/SessionsView.tsx @@ -174,9 +174,9 @@ export function SessionsView({ personIds, isPersonPage = false }: SessionsTableP return (
- )} diff --git a/frontend/src/scenes/sessions/filters/EditFiltersPanel.tsx b/frontend/src/scenes/sessions/filters/EditFiltersPanel.tsx index 17999c0af79..c11eb13a56c 100644 --- a/frontend/src/scenes/sessions/filters/EditFiltersPanel.tsx +++ b/frontend/src/scenes/sessions/filters/EditFiltersPanel.tsx @@ -132,7 +132,7 @@ export function EditFiltersPanel({ onSubmit }: Props): JSX.Element | null { Save filter -