From efc2864eacea758d4969c161dd5d9ad93141e254 Mon Sep 17 00:00:00 2001 From: Swikriti Tripathi <41103328+SwikritiT@users.noreply.github.com> Date: Fri, 29 Apr 2022 15:11:13 +0545 Subject: [PATCH] [tests-only] Adds e2e tests for download files batch action (#6541) * Add test step for downloading file using batch action Signed-off-by: Swikriti Tripathi * Address reviews * change selector --- tests/e2e/README.md | 2 +- .../features/integrations/link.oc10.feature | 35 ++++++++ .../{link.feature => link.ocis.feature} | 12 +-- .../features/integrations/share.feature | 2 +- .../features/journeys/kindergarten.feature | 8 +- .../e2e/cucumber/steps/app-files/resource.ts | 47 ++++++++--- .../support/objects/app-files/page/public.ts | 9 ++ .../objects/app-files/resource/actions.ts | 83 ++++++++++++++++--- 8 files changed, 164 insertions(+), 34 deletions(-) create mode 100644 tests/e2e/cucumber/features/integrations/link.oc10.feature rename tests/e2e/cucumber/features/integrations/{link.feature => link.ocis.feature} (79%) diff --git a/tests/e2e/README.md b/tests/e2e/README.md index 523196a8432..94c0dc85c46 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -21,7 +21,7 @@ Please make sure to point http://host.docker.internal/ to 127.0.0.1 by adding it ```shell $ yarn && yarn build:w $ docker-compose up oc10 ocis -$ yarn test:e2e:cucumber tests/e2e/cucumber/ +$ yarn test:e2e:cucumber tests/e2e/cucumber/features ``` ## Available options diff --git a/tests/e2e/cucumber/features/integrations/link.oc10.feature b/tests/e2e/cucumber/features/integrations/link.oc10.feature new file mode 100644 index 00000000000..11c10902d32 --- /dev/null +++ b/tests/e2e/cucumber/features/integrations/link.oc10.feature @@ -0,0 +1,35 @@ +Feature: link + + @issue-6239 + Scenario: public link in oc10 + Given "Admin" creates following users + | id | + | Alice | + When "Alice" logs in + And "Alice" opens the "files" app + And "Alice" creates the following resources + | resource | type | + | folderPublic | folder | + And "Alice" uploads the following resources + | resource | to | + | lorem.txt | folderPublic | + # Then "Alice" should see the following resource + # | folderPublic/lorem.txt | + And "Alice" creates a public link for the following resource using the sidebar panel + | resource | name | role | dateOfExpiration | password | + | folderPublic | myPublicLink | uploader | +5 days | 12345 | + And "Alice" logs out + # Then "Alice" should see 1 public link + When "Anonymous" opens the public link "myPublicLink" + And "Anonymous" unlocks the public link with password "12345" + # Then the public should not see the following resource + # | lorem.txt | + And "Anonymous" drop uploads following resources + | resource | + | textfile.txt | + # Then the public should see the following files on the files-drop page + # | textfile.txt | + # When the public reloads the public link pages + # Then the public should not see the following files on the files-drop page + # | textfile.txt | + And "Anonymous" logs out diff --git a/tests/e2e/cucumber/features/integrations/link.feature b/tests/e2e/cucumber/features/integrations/link.ocis.feature similarity index 79% rename from tests/e2e/cucumber/features/integrations/link.feature rename to tests/e2e/cucumber/features/integrations/link.ocis.feature index b6cda6eea6e..ab03daffbcc 100644 --- a/tests/e2e/cucumber/features/integrations/link.feature +++ b/tests/e2e/cucumber/features/integrations/link.ocis.feature @@ -14,10 +14,9 @@ Feature: link | lorem.txt | folderPublic | #Then "Alice" should see the following resource # | folderPublic/lorem.txt | - When "Alice" creates a public link for the following resource using the sidebar panel + And "Alice" creates a public link for the following resource using the sidebar panel | resource | name | role | dateOfExpiration | password | | folderPublic | myPublicLink | uploader | +5 days | 12345 | - When "Alice" logs out #Then "Alice" should see 1 public link When "Anonymous" opens the public link "myPublicLink" And "Anonymous" unlocks the public link with password "12345" @@ -31,6 +30,9 @@ Feature: link #When the public reloads the public link pages #Then the public should not see the following files on the files-drop page # | textfile.txt | - When "Anonymous" logs out - - + And "Anonymous" logs out + When "Alice" downloads the following resources using the batch action + | resource | from | + | lorem.txt | folderPublic | + | textfile.txt | folderPublic | + And "Alice" logs out diff --git a/tests/e2e/cucumber/features/integrations/share.feature b/tests/e2e/cucumber/features/integrations/share.feature index 7966228bf1b..487af8f361e 100644 --- a/tests/e2e/cucumber/features/integrations/share.feature +++ b/tests/e2e/cucumber/features/integrations/share.feature @@ -87,7 +87,7 @@ Feature: share And "Brian" copies the following resource | resource | to | | Shares/testavatar.jpeg | Personal | - And "Brian" downloads the following resource + And "Brian" downloads the following resource using the sidebar panel | resource | from | | testavatar.jpeg | Shares | And "Alice" updates following sharee role diff --git a/tests/e2e/cucumber/features/journeys/kindergarten.feature b/tests/e2e/cucumber/features/journeys/kindergarten.feature index 8d551a391b3..6bb353ca2bb 100644 --- a/tests/e2e/cucumber/features/journeys/kindergarten.feature +++ b/tests/e2e/cucumber/features/journeys/kindergarten.feature @@ -47,7 +47,7 @@ Feature: Kindergarten can use web to organize a day | name | | meal plan | And "Brian" navigates to the personal space page - And "Brian" downloads the following resources + And "Brian" downloads the following resources using the sidebar panel | resource | from | | data.zip | Shares/meal plan | # Then what do we check for to be confident that the above things done by Brian have worked? @@ -59,7 +59,7 @@ Feature: Kindergarten can use web to organize a day | name | | meal plan | And "Carol" navigates to the personal space page - And "Carol" downloads the following resources + And "Carol" downloads the following resources using the sidebar panel | resource | from | | data.zip | Shares/meal plan | | lorem.txt | Shares/meal plan | @@ -67,14 +67,14 @@ Feature: Kindergarten can use web to organize a day # Then what do we check for to be confident that the above things done by Carol have worked? # Then the downloaded files should have content "abc..." And "Carol" logs out - When "Brian" downloads the following resources + When "Brian" downloads the following resources using the sidebar panel | resource | from | | lorem.txt | Shares/meal plan | | lorem-big.txt | Shares/meal plan | # Then what do we check for to be confident that the above things done by Brian have worked? # Then the downloaded files should have content "abc..." And "Brian" logs out - And "Alice" downloads the following resources + And "Alice" downloads the following resources using the sidebar panel | resource | from | | parent.txt | groups/Kindergarten Koalas/meal plan | | lorem.txt | groups/Kindergarten Koalas/meal plan | diff --git a/tests/e2e/cucumber/steps/app-files/resource.ts b/tests/e2e/cucumber/steps/app-files/resource.ts index 590ba684d9c..41205793693 100644 --- a/tests/e2e/cucumber/steps/app-files/resource.ts +++ b/tests/e2e/cucumber/steps/app-files/resource.ts @@ -1,4 +1,4 @@ -import { DataTable, Given, When } from '@cucumber/cucumber' +import { DataTable, When } from '@cucumber/cucumber' import { World } from '../../environment' import { objects } from '../../../support' import { expect } from '@playwright/test' @@ -34,11 +34,19 @@ When( } ) -Given( - '{string} downloads the following resource(s)', - async function (this: World, stepUser: string, stepTable: DataTable) { +When( + /^"([^"]*)" downloads the following resource(s)? using the (sidebar panel|batch action)$/, + async function ( + this: World, + stepUser: string, + _: string, + actionType: string, + stepTable: DataTable + ) { const { page } = this.actorsEnvironment.getActor({ key: stepUser }) const resourceObject = new objects.applicationFiles.Resource({ page }) + let downloads + let files const downloadInfo = stepTable.hashes().reduce((acc, stepRow) => { const { resource, from } = stepRow @@ -52,13 +60,32 @@ Given( }, {}) for (const folder of Object.keys(downloadInfo)) { - const files = downloadInfo[folder] - const downloads = await resourceObject.download({ folder, names: files }) - - expect(files.length).toBe(downloads.length) - downloads.forEach((download) => { - expect(files).toContain(download.suggestedFilename()) + files = downloadInfo[folder] + downloads = await resourceObject.download({ + folder, + names: files, + via: actionType === 'batch action' ? 'BATCH_ACTION' : 'SIDEBAR_PANEL' }) + if (actionType === 'sidebar panel') { + expect(files.length).toBe(downloads.length) + downloads.forEach((download) => { + expect(files).toContain(download.suggestedFilename()) + }) + } + } + + if (actionType === 'batch action') { + if (files.length === 1) { + expect(files.length).toBe(downloads.length) + downloads.forEach((download) => { + expect(files[0]).toBe(download.suggestedFilename()) + }) + } else { + expect(downloads.length).toBe(1) + downloads.forEach((download) => { + expect(download.suggestedFilename()).toBe('download.tar') + }) + } } } ) diff --git a/tests/e2e/support/objects/app-files/page/public.ts b/tests/e2e/support/objects/app-files/page/public.ts index 2f5e85a3338..0bf0e9f7b87 100644 --- a/tests/e2e/support/objects/app-files/page/public.ts +++ b/tests/e2e/support/objects/app-files/page/public.ts @@ -1,5 +1,7 @@ import { Page } from 'playwright' import { File } from '../../../types' +import util from 'util' +import path from 'path' export class Public { #page: Page @@ -22,8 +24,15 @@ export class Public { } async upload({ resources }: { resources: File[] }): Promise { + const startUrl = this.#page.url() + const resourceSelector = `[data-test-resource-name="%s"]` await this.#page .locator('//input[@id="fileUploadInput"]') .setInputFiles(resources.map((file) => file.path)) + const names = resources.map((file) => path.basename(file.name)) + await Promise.all( + names.map((name) => this.#page.waitForSelector(util.format(resourceSelector, name))) + ) + await this.#page.goto(startUrl) } } diff --git a/tests/e2e/support/objects/app-files/resource/actions.ts b/tests/e2e/support/objects/app-files/resource/actions.ts index 1299c624fe4..80b16c213df 100644 --- a/tests/e2e/support/objects/app-files/resource/actions.ts +++ b/tests/e2e/support/objects/app-files/resource/actions.ts @@ -1,9 +1,15 @@ import { Download, Page } from 'playwright' +import util from 'util' import { resourceExists, waitForResources } from './utils' import path from 'path' import { File } from '../../../types' import { sidebar } from '../utils' +const downloadButtonSideBar = '#oc-files-actions-sidebar .oc-files-actions-download-file-trigger' +const downloadButtonBatchActionSingleFile = '.oc-files-actions-download-file-trigger' +const downloadButtonBatchActionMultiple = '.oc-files-actions-download-archive-trigger' +const checkBox = `//*[@data-test-resource-name="%s"]//ancestor::tr//input` + export const clickResource = async ({ page, path @@ -92,33 +98,84 @@ export interface downloadResourcesArgs { page: Page names: string[] folder: string + via: 'SIDEBAR_PANEL' | 'BATCH_ACTION' } export const downloadResources = async (args: downloadResourcesArgs): Promise => { - const { page, names, folder } = args + const { page, names, folder, via } = args const downloads = [] - if (folder) { - await clickResource({ page, path: folder }) - } + switch (via) { + case 'SIDEBAR_PANEL': { + if (folder) { + await clickResource({ page, path: folder }) + } - for (const name of names) { - await sidebar.open({ page: page, resource: name }) - await sidebar.openPanel({ page: page, name: 'actions' }) + for (const name of names) { + await sidebar.open({ page: page, resource: name }) + await sidebar.openPanel({ page: page, name: 'actions' }) - const [download] = await Promise.all([ - page.waitForEvent('download'), - page.locator('#oc-files-actions-sidebar .oc-files-actions-download-file-trigger').click() - ]) + const [download] = await Promise.all([ + page.waitForEvent('download'), + page.locator(downloadButtonSideBar).click() + ]) + + await sidebar.close({ page: page }) - await sidebar.close({ page: page }) + downloads.push(download) + } + break + } - downloads.push(download) + case 'BATCH_ACTION': { + await selectOrDeselectResources({ page: page, names: names, folder: folder, select: true }) + let downloadSelector = downloadButtonBatchActionMultiple + if (names.length === 1) { + downloadSelector = downloadButtonBatchActionSingleFile + } + const [download] = await Promise.all([ + page.waitForEvent('download'), + page.locator(downloadSelector).click() + ]) + downloads.push(download) + break + } } return downloads } +export type selectResourcesArgs = { + page: Page + names: string[] + folder: string + select: boolean +} + +export const selectOrDeselectResources = async (args: selectResourcesArgs): Promise => { + const { page, folder, names, select } = args + if (folder) { + await clickResource({ page: page, path: folder }) + } + + for (const resource of names) { + const exists = await resourceExists({ + page: page, + name: resource + }) + if (exists) { + const resourceCheckbox = page.locator(util.format(checkBox, resource)) + if (!(await resourceCheckbox.isChecked()) && select) { + await resourceCheckbox.check() + } else if (await resourceCheckbox.isChecked()) { + await resourceCheckbox.uncheck() + } + } else { + throw new Error(`The resource ${resource} you are trying to select does not exist`) + } + } +} + /**/ export interface moveOrCopyResourceArgs {