From 2b034f857c651069944b035e2b11c5c6135fcb39 Mon Sep 17 00:00:00 2001 From: Olga Bulat Date: Fri, 28 Jul 2023 14:25:41 +0300 Subject: [PATCH] Extract reusable VAudioCollection.vue (#2695) * Extract reusable VAudioCollection.vue Co-authored-by: Zack Krida * Move analytics test to e2e * Move the gap setting to the `ol` level --------- Co-authored-by: Zack Krida --- .../VAudioDetails/VRelatedAudio.vue | 66 ++-------- .../components/VAudioTrack/VAudioTrack.vue | 21 ++- .../VSearchResultsGrid/VAllResultsGrid.vue | 18 +-- .../VSearchResultsGrid/VAudioCell.vue | 12 ++ .../VSearchResultsGrid/VAudioCollection.vue | 91 +++++++++++++ .../VSearchResultsGrid/VAudioList.vue | 124 ++++++++++++++++++ frontend/src/pages/search.vue | 2 +- frontend/src/pages/search/audio.vue | 112 +++++----------- frontend/src/pages/search/image.vue | 29 ++-- frontend/src/pages/search/index.vue | 3 - .../src/pages/search/search-page.types.ts | 29 ---- frontend/src/types/events.ts | 1 + .../e2e/all-results-analytics.spec.ts | 75 +++++++++++ .../VSearchResultsGrid/v-audio-cell.spec.js | 49 ------- .../VSearchResultsGrid/v-image-cell.spec.js | 19 --- 15 files changed, 386 insertions(+), 265 deletions(-) create mode 100644 frontend/src/components/VSearchResultsGrid/VAudioCollection.vue create mode 100644 frontend/src/components/VSearchResultsGrid/VAudioList.vue delete mode 100644 frontend/src/pages/search/search-page.types.ts create mode 100644 frontend/src/types/events.ts create mode 100644 frontend/test/playwright/e2e/all-results-analytics.spec.ts delete mode 100644 frontend/test/unit/specs/components/VSearchResultsGrid/v-audio-cell.spec.js diff --git a/frontend/src/components/VAudioDetails/VRelatedAudio.vue b/frontend/src/components/VAudioDetails/VRelatedAudio.vue index ff4e72878a4..a5cacb356c7 100644 --- a/frontend/src/components/VAudioDetails/VRelatedAudio.vue +++ b/frontend/src/components/VAudioDetails/VRelatedAudio.vue @@ -1,72 +1,41 @@ diff --git a/frontend/src/components/VSearchResultsGrid/VAudioList.vue b/frontend/src/components/VSearchResultsGrid/VAudioList.vue new file mode 100644 index 00000000000..bc09d6f9409 --- /dev/null +++ b/frontend/src/components/VSearchResultsGrid/VAudioList.vue @@ -0,0 +1,124 @@ + + + diff --git a/frontend/src/pages/search.vue b/frontend/src/pages/search.vue index 776c381a109..46c7f66151f 100644 --- a/frontend/src/pages/search.vue +++ b/frontend/src/pages/search.vue @@ -15,7 +15,7 @@ diff --git a/frontend/src/pages/search/index.vue b/frontend/src/pages/search/index.vue index 9e7f609e27d..079473bc73e 100644 --- a/frontend/src/pages/search/index.vue +++ b/frontend/src/pages/search/index.vue @@ -5,13 +5,10 @@ diff --git a/frontend/src/pages/search/search-page.types.ts b/frontend/src/pages/search/search-page.types.ts deleted file mode 100644 index ccce5fb7c50..00000000000 --- a/frontend/src/pages/search/search-page.types.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { SupportedMediaType } from "~/constants/media" -import type { Media } from "~/types/media" -import type { FetchState } from "~/types/fetch-state" - -import type { ExtractPropTypes, PropType } from "vue" - -export const propTypes = { - resultItems: { - type: Object as PropType>, - required: true, - }, - fetchState: { - type: Object as PropType, - required: true, - }, - isFilterVisible: { - type: Boolean, - required: false, - }, - searchTerm: { - type: String, - required: true, - }, - supported: { - type: Boolean, - required: false, - }, -} -export type SearchPageProps = ExtractPropTypes diff --git a/frontend/src/types/events.ts b/frontend/src/types/events.ts new file mode 100644 index 00000000000..d3d20857966 --- /dev/null +++ b/frontend/src/types/events.ts @@ -0,0 +1 @@ +export type AudioTrackClickEvent = { event: MouseEvent; inWaveform: boolean } diff --git a/frontend/test/playwright/e2e/all-results-analytics.spec.ts b/frontend/test/playwright/e2e/all-results-analytics.spec.ts new file mode 100644 index 00000000000..353ffc56e63 --- /dev/null +++ b/frontend/test/playwright/e2e/all-results-analytics.spec.ts @@ -0,0 +1,75 @@ +import { test } from "@playwright/test" + +import { openFirstResult } from "~~/test/playwright/utils/navigation" +import { + collectAnalyticsEvents, + expectEventPayloadToMatch, +} from "~~/test/playwright/utils/analytics" + +import { AUDIO, IMAGE } from "~/constants/media" + +test.describe("all results grid analytics test", () => { + test.beforeEach(async ({ page }) => { + await page.goto("/search/?q=birds") + }) + + test("should send SELECT_SEARCH_RESULT event when audio result is selected", async ({ + context, + page, + }) => { + const analyticsEvents = collectAnalyticsEvents(context) + await openFirstResult(page, "audio") + const selectSearchResultEvent = analyticsEvents.find( + (event) => event.n === "SELECT_SEARCH_RESULT" + ) + expectEventPayloadToMatch(selectSearchResultEvent, { + mediaType: AUDIO, + query: "birds", + relatedTo: null, + id: "2e38ac1e-830c-4e9c-b13d-2c9a1ad53f95", + provider: "jamendo", + }) + }) + test("should send SELECT_SEARCH_RESULT event when image result is selected", async ({ + context, + page, + }) => { + const analyticsEvents = collectAnalyticsEvents(context) + await openFirstResult(page, "image") + const selectSearchResultEvent = analyticsEvents.find( + (event) => event.n === "SELECT_SEARCH_RESULT" + ) + + expectEventPayloadToMatch(selectSearchResultEvent, { + id: "da5cb478-c093-4d62-b721-cda18797e3fb", + mediaType: IMAGE, + query: "birds", + provider: "flickr", + relatedTo: null, + }) + }) + + test("should send AUDIO_INTERACTION event when audio is interacted", async ({ + page, + }) => { + const analyticsEvents = collectAnalyticsEvents(page.context()) + + const firstResultPlay = page + .locator(`a[href*="/audio/"]`) + .first() + .locator(`[aria-label="Play"]`) + + await firstResultPlay.click() + + const audioInteractionEvent = analyticsEvents.find( + (event) => event.n === "AUDIO_INTERACTION" + ) + + expectEventPayloadToMatch(audioInteractionEvent, { + id: "2e38ac1e-830c-4e9c-b13d-2c9a1ad53f95", + event: "play", + provider: "jamendo", + component: "VAllResultsGrid", + }) + }) +}) diff --git a/frontend/test/unit/specs/components/VSearchResultsGrid/v-audio-cell.spec.js b/frontend/test/unit/specs/components/VSearchResultsGrid/v-audio-cell.spec.js deleted file mode 100644 index ab6a55519ec..00000000000 --- a/frontend/test/unit/specs/components/VSearchResultsGrid/v-audio-cell.spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { fireEvent } from "@testing-library/vue" - -import { render } from "~~/test/unit/test-utils/render" - -import { getAudioObj } from "~~/test/unit/fixtures/audio" - -import { useAnalytics } from "~/composables/use-analytics" -import { AUDIO } from "~/constants/media" - -import VAudioCell from "~/components/VSearchResultsGrid/VAudioCell.vue" - -jest.mock("~/composables/use-analytics", () => ({ - useAnalytics: jest.fn(), -})) - -describe("VAudioCell", () => { - let options = {} - let sendCustomEventMock = null - const audio = getAudioObj() - - beforeEach(() => { - sendCustomEventMock = jest.fn() - useAnalytics.mockImplementation(() => ({ - sendCustomEvent: sendCustomEventMock, - })) - options = { - props: { - audio, - searchTerm: "cat", - relatedTo: null, - }, - } - }) - - it("sends SELECT_SEARCH_RESULT event when clicked", async () => { - const { getByRole } = render(VAudioCell, options) - const link = getByRole("application") - - await fireEvent.click(link) - - expect(sendCustomEventMock).toHaveBeenCalledWith("SELECT_SEARCH_RESULT", { - id: audio.id, - mediaType: AUDIO, - query: "cat", - provider: audio.provider, - relatedTo: null, - }) - }) -}) diff --git a/frontend/test/unit/specs/components/VSearchResultsGrid/v-image-cell.spec.js b/frontend/test/unit/specs/components/VSearchResultsGrid/v-image-cell.spec.js index 17de7621956..e3d02ba5fac 100644 --- a/frontend/test/unit/specs/components/VSearchResultsGrid/v-image-cell.spec.js +++ b/frontend/test/unit/specs/components/VSearchResultsGrid/v-image-cell.spec.js @@ -1,12 +1,8 @@ -import { fireEvent } from "@testing-library/vue" - import { render } from "~~/test/unit/test-utils/render" import { image } from "~~/test/unit/fixtures/image" import { useAnalytics } from "~/composables/use-analytics" -import { IMAGE } from "~/constants/media" - import VImageCell from "~/components/VSearchResultsGrid/VImageCell.vue" jest.mock("~/composables/use-analytics", () => ({ @@ -31,21 +27,6 @@ describe("VImageCell", () => { } }) - it("sends SELECT_SEARCH_RESULT event when clicked", async () => { - const { getByRole } = render(VImageCell, options) - const link = getByRole("link") - - await fireEvent.click(link) - - expect(sendCustomEventMock).toHaveBeenCalledWith("SELECT_SEARCH_RESULT", { - id: image.id, - mediaType: IMAGE, - query: "cat", - provider: image.provider, - relatedTo: null, - }) - }) - it("is blurred when the image is sensitive", async () => { options.props.image.isSensitive = true const { getByAltText } = render(VImageCell, options)