diff --git a/.drone.star b/.drone.star index ad2466a7332..ffd7ea5403c 100644 --- a/.drone.star +++ b/.drone.star @@ -198,6 +198,13 @@ config = { "search", ], }, + "4": { + "earlyFail": True, + "skip": False, + "suites": [ + "user-settings", + ], + }, }, "build": True, } diff --git a/tests/e2e-playwright/specs/shares/denyShareAccess.spec.ts b/tests/e2e-playwright/specs/shares/denyShareAccess.spec.ts index fc4a8f396b2..b884f2235a8 100644 --- a/tests/e2e-playwright/specs/shares/denyShareAccess.spec.ts +++ b/tests/e2e-playwright/specs/shares/denyShareAccess.spec.ts @@ -54,7 +54,7 @@ test.describe('deny share access', () => { actions: 'QUICK_ACTION' }) - await ui.openResource({ actorsEnvironment, stepUser: 'Alice', resource: 'folder_to_shared' }) + await ui.openFolder({ actorsEnvironment, stepUser: 'Alice', resource: 'folder_to_shared' }) await ui.shareResource({ actorsEnvironment, @@ -83,7 +83,7 @@ test.describe('deny share access', () => { }) await ui.navigateToSharedWithMePage({ actorsEnvironment, stepUser: 'Brian' }) - await ui.openResource({ actorsEnvironment, stepUser: 'Brian', resource: 'folder_to_shared' }) + await ui.openFolder({ actorsEnvironment, stepUser: 'Brian', resource: 'folder_to_shared' }) expect( await ui.resourceExists({ actorsEnvironment, @@ -99,7 +99,7 @@ test.describe('deny share access', () => { name: 'files' }) - await ui.openResource({ actorsEnvironment, stepUser: 'Alice', resource: 'folder_to_shared' }) + await ui.openFolder({ actorsEnvironment, stepUser: 'Alice', resource: 'folder_to_shared' }) // allow access - deleting "Cannot access" share @@ -112,7 +112,7 @@ test.describe('deny share access', () => { }) await ui.openApplication({ actorsEnvironment, stepUser: 'Brian', name: 'files' }) await ui.navigateToSharedWithMePage({ actorsEnvironment, stepUser: 'Brian' }) - await ui.openResource({ actorsEnvironment, stepUser: 'Brian', resource: 'folder_to_shared' }) + await ui.openFolder({ actorsEnvironment, stepUser: 'Brian', resource: 'folder_to_shared' }) expect( await ui.resourceExists({ actorsEnvironment, diff --git a/tests/e2e-playwright/specs/user-settings/tiles.spec.ts b/tests/e2e-playwright/specs/user-settings/tiles.spec.ts new file mode 100644 index 00000000000..e573e0824a0 --- /dev/null +++ b/tests/e2e-playwright/specs/user-settings/tiles.spec.ts @@ -0,0 +1,76 @@ +import { test } from '@playwright/test' +import { config } from './../../../e2e/config.js' +import { ActorsEnvironment, UsersEnvironment } from '../../../e2e/support/environment' +import { setAccessAndRefreshToken } from '../../helpers/setAccessAndRefreshToken' +import * as api from '../../steps/api/api' +import * as ui from '../../steps/ui/index' + +test.describe('tiles view', { tag: '@predefined-users' }, () => { + let actorsEnvironment: ActorsEnvironment + const usersEnvironment = new UsersEnvironment() + + test.beforeEach(async ({ browser }) => { + actorsEnvironment = new ActorsEnvironment({ + context: { + acceptDownloads: config.acceptDownloads, + reportDir: config.reportDir, + tracingReportDir: config.tracingReportDir, + reportHar: config.reportHar, + reportTracing: config.reportTracing, + reportVideo: config.reportVideo, + failOnUncaughtConsoleError: config.failOnUncaughtConsoleError + }, + browser: browser + }) + + await setAccessAndRefreshToken(usersEnvironment) + + // Given "Admin" creates following user using API + await api.userHasBeenCreated({ usersEnvironment, stepUser: 'Admin', userToBeCreated: 'Alice' }) + // And "Alice" logs in + await ui.logInUser({ usersEnvironment, actorsEnvironment, stepUser: 'Alice' }) + // And "Alice" creates the following resources + await api.userHasCreatedFolder({ + usersEnvironment, + stepUser: 'Alice', + folderName: 'tile_folder' + }) + }) + + test.afterEach(async () => { + await api.deleteUser({ usersEnvironment, stepUser: 'Admin', targetUser: 'Alice' }) + }) + + test('Users can navigate web via tiles', async () => { + // When "Alice" switches to the tiles-view + await ui.switchToTilesViewMode({ + actorsEnvironment, + stepUser: 'Alice' + }) + // Then "Alice" sees the resources displayed as tiles + await ui.shouldSeeResourcesAsTiles({ + actorsEnvironment, + stepUser: 'Alice' + }) + // And "Alice" opens folder "tile_folder" + await ui.openFolder({ + actorsEnvironment, + stepUser: 'Alice', + resource: 'tile_folder' + }) + // And "Alice" creates the following resources + await ui.createResource({ + actorsEnvironment, + stepUser: 'Alice', + type: 'folder', + resource: 'tile_folder/tile_folder2' + }) + // And "Alice" sees the resources displayed as tiles + await ui.shouldSeeResourcesAsTiles({ + actorsEnvironment, + stepUser: 'Alice' + }) + // And "Alice" logs out + await ui.logOutUser({ actorsEnvironment, stepUser: 'Alice' }) + }) +}) diff --git a/tests/e2e-playwright/steps/ui/resources.ts b/tests/e2e-playwright/steps/ui/resources.ts index a06987da311..767669f51ad 100644 --- a/tests/e2e-playwright/steps/ui/resources.ts +++ b/tests/e2e-playwright/steps/ui/resources.ts @@ -99,7 +99,31 @@ export async function searchGloballyWithFilter({ }) } -export async function openResource({ +export async function switchToTilesViewMode({ + actorsEnvironment, + stepUser +}: { + actorsEnvironment: ActorsEnvironment + stepUser: string +}): Promise { + const { page } = actorsEnvironment.getActor({ key: stepUser }) + const resourceObject = new objects.applicationFiles.Resource({ page }) + await resourceObject.switchToTilesViewMode() +} + +export async function shouldSeeResourcesAsTiles({ + actorsEnvironment, + stepUser +}: { + actorsEnvironment: ActorsEnvironment + stepUser: string +}): Promise { + const { page } = actorsEnvironment.getActor({ key: stepUser }) + const resourceObject = new objects.applicationFiles.Resource({ page }) + await resourceObject.expectThatResourcesAreTiles() +} + +export async function openFolder({ actorsEnvironment, stepUser, resource diff --git a/tests/e2e/cucumber/features/user-settings/tiles.feature b/tests/e2e/cucumber/features/user-settings/tiles.feature deleted file mode 100644 index c98c755ceed..00000000000 --- a/tests/e2e/cucumber/features/user-settings/tiles.feature +++ /dev/null @@ -1,22 +0,0 @@ -@predefined-users -Feature: Tiles - As a user - I want to view and navigate resources displayed as tiles - So that I can identify them better - - Scenario: Users can navigate web via tiles - Given "Admin" creates following user using API - | id | - | Alice | - And "Alice" logs in - And "Alice" creates the following resources - | resource | type | - | tile_folder | folder | - And "Alice" switches to the tiles-view - And "Alice" sees the resources displayed as tiles - And "Alice" opens folder "tile_folder" - And "Alice" creates the following resources - | resource | type | - | tile_folder2 | folder | - And "Alice" sees the resources displayed as tiles - And "Alice" logs out diff --git a/tests/e2e/support/objects/a11y/actions.ts b/tests/e2e/support/objects/a11y/actions.ts index 25b52357902..29b3c7a3146 100644 --- a/tests/e2e/support/objects/a11y/actions.ts +++ b/tests/e2e/support/objects/a11y/actions.ts @@ -30,7 +30,12 @@ export const selectors = { uploadMenuDropdown: '#upload-menu-drop', appSidebar: '#app-sidebar', removeUserModal: '.oc-modal.oc-modal-danger', - appSwitcherDropdown: '#app-switcher-dropdown' + appSwitcherDropdown: '#app-switcher-dropdown', + tippyBox: '.tippy-box', + textEditor: '#text-editor-component', + topBar: '#oc-topbar', + displayOptions: '#files-app-bar-controls-right', + ocCard: '.oc-card' } const a11yRuleTags = ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'best-practice'] diff --git a/tests/e2e/support/objects/app-files/resource/actions.ts b/tests/e2e/support/objects/app-files/resource/actions.ts index cdb60d79321..38a57ae567e 100644 --- a/tests/e2e/support/objects/app-files/resource/actions.ts +++ b/tests/e2e/support/objects/app-files/resource/actions.ts @@ -350,6 +350,14 @@ export const createPasswordProtectedFolder = async ({ password: string }): Promise => { password = substitute(password) + const a11yObject = new objects.a11y.Accessibility({ page }) + const violations = await a11yObject.getSevereAccessibilityViolations( + a11yObject.getSelectors().ocModal + ) + expect( + violations, + `Found ${violations.length} severe accessibility violations in create new folder modal` + ).toHaveLength(0) await page.locator(passwordProtectedFolderButton).click() await page.locator(passwordProtectedFolderNameInput).fill(resource) await page.locator(passwordProtectedFolderPasswordInput).fill(password) @@ -379,6 +387,14 @@ export const createPasswordProtectedFolder = async ({ export const createNewFileOrFolder = async (args: createResourceArgs): Promise => { const { page, name, type, content, password } = args await page.locator(addNewResourceButton).click() + const a11yObject = new objects.a11y.Accessibility({ page }) + const violations = await a11yObject.getSevereAccessibilityViolations( + a11yObject.getSelectors().tippyBox + ) + expect( + violations, + `Found ${violations.length} severe accessibility violations in create new tippy box` + ).toHaveLength(0) switch (type) { case 'folder': { await createNewFolder({ page, resource: name }) @@ -440,6 +456,14 @@ const createDocumentFile = async ( `The document of type ${type} did not appear in the webUI for ${editorToOpen}. Possible reason could be the app provider service for ${editorToOpen} was not ready yet.` ) } + const a11yObject = new objects.a11y.Accessibility({ page }) + const violations = await a11yObject.getSevereAccessibilityViolations( + a11yObject.getSelectors().ocModal + ) + expect( + violations, + `Found ${violations.length} severe accessibility violations in create new folder modal` + ).toHaveLength(0) await page.locator(util.format(createNewOfficeDocumentFileButton, type)).click() await page.locator(resourceNameInput).clear() await page.locator(resourceNameInput).fill(name) @@ -569,6 +593,19 @@ export const editTextDocument = async ({ const inputLocator = isMarkdownMode === 'true' ? textEditorMarkdownInput : textEditorPlainTextInput + const a11yObject = new objects.a11y.Accessibility({ page }) + let violations = await a11yObject.getSevereAccessibilityViolations( + a11yObject.getSelectors().textEditor + ) + violations = [ + ...violations, + ...(await a11yObject.getSevereAccessibilityViolations(a11yObject.getSelectors().topBar)) + ] + expect( + violations, + `Found ${violations.length} severe accessibility violations in text editor` + ).toHaveLength(0) + await page.locator(inputLocator).fill(content) await Promise.all([ page.waitForResponse((resp) => resp.status() === 204 && resp.request().method() === 'PUT'), @@ -1658,11 +1695,27 @@ export interface switchViewModeArgs { export const clickViewModeToggle = async (args: switchViewModeArgs): Promise => { const { page, target } = args + const a11yObject = new objects.a11y.Accessibility({ page }) + const a11yViolations = await a11yObject.getSevereAccessibilityViolations( + a11yObject.getSelectors().displayOptions + ) + expect( + a11yViolations, + `Found ${a11yViolations.length} severe accessibility violations in file controls modal` + ).toHaveLength(0) await page.locator(`.viewmode-switch-buttons .${target}`).click() } export const expectThatResourcesAreTiles = async (args: { page: Page }): Promise => { const { page } = args + const a11yObject = new objects.a11y.Accessibility({ page }) + const a11yViolations = await a11yObject.getSevereAccessibilityViolations( + a11yObject.getSelectors().tilesView + ) + expect( + a11yViolations, + `Found ${a11yViolations.length} severe accessibility violations in file tile view` + ).toHaveLength(0) const tiles = page.locator(resourcesAsTiles) await expect(tiles).toBeVisible() }