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

Add mobile e2e tests #14

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@ dotenv.config()

export default defineConfig({
chromeWebSecurity: false,
component: {
devServer: {
framework: 'vue',
bundler: 'vite',
},
},
env: {
language: 'xx',
mobileViewportWidthBreakpoint: 640,
testUser: {
username: process.env.TEST_USER_USERNAME,
password: process.env.TEST_USER_PASSWORD,
},
},
component: {
devServer: {
framework: 'vue',
bundler: 'vite',
},
},
e2e: {
baseUrl: 'http://localhost:3000',
viewportHeight: 660,
viewportWidth: 1000,
defaultCommandTimeout: 10000,
experimentalRunAllSpecs: true,
},
})
57 changes: 42 additions & 15 deletions cypress/e2e/dictionary.cy.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
/// <reference types="cypress" />

import { elSelector, withLang } from '@@/cypress/utils'
import {
elSelector,
isMobile,
withLang,
} from '@@/cypress/utils'
import { EWordStatus } from '@/services/dbstore/dto/Words'
import { EDataTest, EDataTestClass } from '@/enums/EDataTest'
import { EPageName } from '@/enums/EPageName'

describe('workspace dictionary', () => {
beforeEach(() => {
Expand All @@ -17,19 +22,24 @@ describe('workspace dictionary', () => {
.el(EDataTest.landing_go_to_workspace_button).click()
.location('pathname').should('equal', withLang('/dictionary'))

cy
.log('visit dictionary using workspace menu')
.visit(withLang('/trainings'))
.el(EDataTest.workspace_navigation_item).contains('dictionary').click()
.location('pathname').should('equal', withLang('/dictionary'))
if (isMobile())
cy.getWorkspaceBottomMenuItem(EPageName.DICTIONARY).click()
else
cy.el(EDataTest.workspace_navigation_item).contains('dictionary').click()
cy.location('pathname').should('equal', withLang('/dictionary'))

.log('check if filters are clear')
cy.log('check if filters are clear')
.el(EDataTest.words_container_header_checkbox).should('not.be.checked')
.el(EDataTest.words_container_header_search).should('have.value', '')
.elByClass(EDataTestClass.words_container_header_status_active).contains('all')

// For mobile
// cy.el(EDataTest.words_container_header_status)
// .contains('All')
if (isMobile())
cy.el(EDataTest.words_container_header_status).contains('all')
else
cy.elByClass(EDataTestClass.words_container_header_status_active).contains('all')

})
})

Expand Down Expand Up @@ -182,15 +192,28 @@ describe('workspace dictionary', () => {
.log('check if all source words contain search word')
.el(EDataTest.words_list_item_source_word).should('contain', searchText)

cy
.log('change filtered status to "Learned"')
.el(EDataTest.words_container_header_status).eq(EWordStatus.LEARNED + 1).click()
if (isMobile())
cy
.el(EDataTest.words_container_header_status).click()
.elByClass(EDataTestClass.words_container_header_status).contains('learned').click()
else
cy.el(EDataTest.words_container_header_status).eq(EWordStatus.LEARNED + 1).click()

cy
.log('check if words not found')
.el(EDataTest.words_list_item).should('not.exist')

.log('change filtered status to "Learn"')
.el(EDataTest.words_container_header_status).eq(EWordStatus.NEW_WORD + 1).click()
cy.log('change filtered status to "New work"')
if (isMobile())
cy
.el(EDataTest.words_container_header_status).click()
.elByClass(EDataTestClass.words_container_header_status).contains('new_word').click()
else
cy.el(EDataTest.words_container_header_status).eq(EWordStatus.NEW_WORD + 1).click()

cy
.log('check if words found')
.el(EDataTest.words_list_item).should('exist')

Expand All @@ -199,20 +222,24 @@ describe('workspace dictionary', () => {

.log('change status of first word to "Learn"')
.el(EDataTest.words_list_item_status).eq(0).trigger('mouseenter')
.get('.n-base-select-menu-option-wrapper > :nth-child(2)').click()
.elByClass(EDataTestClass.word_status).contains('learn').should('be.visible').click()

.log('check if word with another status still in list')
.el(EDataTest.words_list_item_status).eq(0).should('have.attr', 'data-test-value', EWordStatus.LEARN)

.log('recover word status')
.log('change status of first word to "New word"')
.el(EDataTest.words_list_item_status).eq(0).trigger('mouseenter')
.get('.n-base-select-menu-option-wrapper > :nth-child(1)').click()
.elByClass(EDataTestClass.word_status).contains('new_word').should('be.visible').click()

.log('change filtered text')
.get(`${elSelector(EDataTest.words_container_header_search)} input`).clear().should('have.value', '')

cy
.log('check if filtered status changed to "All"')
.elByClass(EDataTestClass.words_container_header_status_active).contains('all')
if (isMobile())
cy.el(EDataTest.words_container_header_status).contains('all')
else
cy.elByClass(EDataTestClass.words_container_header_status_active).contains('all')
})
})
})
40 changes: 20 additions & 20 deletions cypress/e2e/localization.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,6 @@
import { EDataTest, EDataTestClass } from '@/enums/EDataTest'

describe('localization', () => {
it('should redirect to url with lang', () => {
cy.logout()
cy.visit('/').location('pathname').should('equal', '/en')

cy.auth({ validateAuth: false })
cy.visit('/dictionary').location('pathname').should('match', new RegExp('^\\/[a-z]{2}'))
})

it('allow to change interface language for unauthorized user', () => {
cy.logout()
cy
.visit('/xx')
.location('pathname').should('equal', '/xx')
.get('html').should('have.attr', 'lang', 'xx')

.visit('/en')
.location('pathname').should('equal', '/en')
.get('html').should('have.attr', 'lang', 'en')
})

it('allow to change interface language for authorized user only in settings', {
env: {
language: '',
Expand Down Expand Up @@ -52,4 +32,24 @@ describe('localization', () => {
.location('pathname').should('equal', '/en/office/settings')
.get('html').should('have.attr', 'lang', 'en')
})

it('should redirect to url with lang', () => {
cy.auth({ validateAuth: false })
cy.visit('/dictionary').location('pathname').should('match', new RegExp('^\\/[a-z]{2}'))

cy.logout()
cy.visit('/').location('pathname').should('equal', '/en')
})

it('allow to change interface language for unauthorized user', () => {
cy.logout()
cy
.visit('/xx')
.location('pathname').should('equal', '/xx')
.get('html').should('have.attr', 'lang', 'xx')

.visit('/en')
.location('pathname').should('equal', '/en')
.get('html').should('have.attr', 'lang', 'en')
})
})
28 changes: 19 additions & 9 deletions cypress/e2e/office.profile.cy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="cypress" />

import { withLang } from '@@/cypress/utils'
import { isMobile, withLang } from '@@/cypress/utils'
import { EPageName } from '@/enums/EPageName'
import { EDataTest } from '@/enums/EDataTest'

Expand All @@ -17,16 +17,26 @@ describe('office profile', () => {
.get('.n-dropdown-option').contains('profile').click()
.location('pathname').should('equal', withLang('/office/profile'))

.log('check if right office menu item selected')
.el(EDataTest.office_menu).should('have.attr', 'data-test-value', EPageName.OFFICE_PROFILE)
if (!isMobile())
cy
.log('check if right office menu item selected')
.el(EDataTest.office_menu).should('have.attr', 'data-test-value', EPageName.OFFICE_PROFILE)

.log('check if display email')
cy.log('check if display email')
.el(EDataTest.office_profile_email).should('contain', Cypress.env('testUser').username)

.log('visit profile page using office menu')
.el(EDataTest.office_menu).contains('settings').click()
.location('pathname').should('equal', withLang('/office/settings'))
.el(EDataTest.office_menu).contains('profile').click()
.location('pathname').should('equal', withLang('/office/profile'))
if (isMobile())
cy
.log('visit profile page using bottom menu')
.visit(withLang('/dictionary')).waitWorkspacePageInit()
.getWorkspaceBottomMenuItem(EPageName.OFFICE_PROFILE).should('be.visible').click()
else
cy
.log('visit profile page using office menu')
.el(EDataTest.office_menu).contains('settings').click()
.location('pathname').should('equal', withLang('/office/settings'))
.el(EDataTest.office_menu).contains('profile').click()

cy.location('pathname').should('equal', withLang('/office/profile'))
})
})
26 changes: 18 additions & 8 deletions cypress/e2e/office.settings.cy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="cypress" />

import { withLang } from '@@/cypress/utils'
import { isMobile, withLang } from '@@/cypress/utils'
import { EPageName } from '@/enums/EPageName'
import { EDataTest } from '@/enums/EDataTest'

Expand All @@ -17,13 +17,23 @@ describe('office settings', () => {
.get('.n-dropdown-option').contains('settings').click()
.location('pathname').should('equal', withLang('/office/settings'))

.log('check if right office menu item selected')
.el(EDataTest.office_menu).should('have.attr', 'data-test-value', EPageName.OFFICE_SETTINGS)
if (!isMobile())
cy
.log('check if right office menu item selected')
.el(EDataTest.office_menu).should('have.attr', 'data-test-value', EPageName.OFFICE_SETTINGS)

.log('visit settings page using office menu')
.el(EDataTest.office_menu).contains('profile').click()
.location('pathname').should('equal', withLang('/office/profile'))
.el(EDataTest.office_menu).contains('settings').click()
.location('pathname').should('equal', withLang('/office/settings'))
if (isMobile())
cy
.log('visit settings page using bottom menu')
.visit(withLang('/dictionary')).waitWorkspacePageInit()
.getWorkspaceBottomMenuItem(EPageName.OFFICE_SETTINGS).should('be.visible').click()
else
cy
.log('visit settings page using office menu')
.el(EDataTest.office_menu).contains('profile').click()
.location('pathname').should('equal', withLang('/office/profile'))
.el(EDataTest.office_menu).contains('settings').click()

cy.location('pathname').should('equal', withLang('/office/settings'))
})
})
14 changes: 11 additions & 3 deletions cypress/e2e/trainings.cy.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
/// <reference types="cypress" />

import { withLang } from '@@/cypress/utils'
import { isMobile, withLang } from '@@/cypress/utils'
import { EDataTest } from '@/enums/EDataTest'
import { EPageName } from '@/enums/EPageName'

describe('workspace trainings', () => {
it('navigate to /trainings using menu and view "Coming soon" status', () => {
cy.auth()
cy.visit(withLang('/dictionary'))
cy.visit(withLang('/dictionary')).waitWorkspacePageInit()

if (isMobile())
cy
.getWorkspaceBottomMenuItem(EPageName.TRAININGS).should('be.visible').click()
else
cy
.el(EDataTest.workspace_navigation_item).contains('trainings').click()

cy
.el(EDataTest.workspace_navigation_item).contains('trainings').click()
.location('pathname').should('equal', withLang('/trainings'))
.el(EDataTest.workspace_content).contains('coming_soon')
})
Expand Down
6 changes: 4 additions & 2 deletions cypress/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

declare namespace Cypress {
import type { EDataTest, EDataTestClass } from '@/enums/EDataTest'
import { type EPageName } from '@/enums/EPageName'
interface Chainable {
el(dataTest: EDataTest): Chainable<JQuery<HTMLBodyElement>>
elByClass(dataTestClass: EDataTestClass): Chainable<JQuery<HTMLBodyElement>>
el(dataTest: EDataTest, options?: Partial<Loggable & Timeoutable & Withinable & Shadow>): Chainable<JQuery<HTMLBodyElement>>
elByClass(dataTestClass: EDataTestClass, options?: Partial<Loggable & Timeoutable & Withinable & Shadow>): Chainable<JQuery<HTMLBodyElement>>
clickOutside(): Chainable<JQuery<HTMLBodyElement>>
getWorkspaceBottomMenuItem(page: EPageName): Chainable<JQuery<HTMLBodyElement>>
}
}
24 changes: 21 additions & 3 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
/// <reference types="cypress" />

import { elSelector } from '@@/cypress/utils'
import { type EDataTest, type EDataTestClass } from '@/enums/EDataTest'
import { EDataTest, type EDataTestClass } from '@/enums/EDataTest'
import { EPageName } from '@/enums/EPageName'

Cypress.Commands.add('el', (dataTest: EDataTest) => cy.get(elSelector(dataTest)))
Cypress.Commands.add('elByClass', (dataTestClass: EDataTestClass) => cy.get(`.${dataTestClass}`))
Cypress.Commands.add('el', (dataTest: EDataTest, options?: Partial<Cypress.Loggable & Cypress.Timeoutable & Cypress.Withinable & Cypress.Shadow>) =>
cy.get(elSelector(dataTest), options))
Cypress.Commands.add('elByClass', (dataTestClass: EDataTestClass, options?: Partial<Cypress.Loggable & Cypress.Timeoutable & Cypress.Withinable & Cypress.Shadow>) =>
cy.get(`.${dataTestClass}`, options))

Cypress.Commands.add('clickOutside', () => {
cy.log('click outside')
Expand All @@ -13,3 +16,18 @@ Cypress.Commands.add('clickOutside', () => {
.get('body', { log: false })
.click(0,0, { log: false })
})

Cypress.Commands.add('getWorkspaceBottomMenuItem', (page: EPageName) => {
switch (page) {
case EPageName.OFFICE_PROFILE:
case EPageName.OFFICE_SETTINGS:
return cy
.get(`${elSelector(EDataTest.workspace_bottom_menu_item)}[data-test-value="${EPageName.OFFICE}"]`).click()
.get(`${elSelector(EDataTest.workspace_bottom_menu_item)}[data-test-value="${page}"]`)
default:
return cy
.get(`${elSelector(EDataTest.workspace_bottom_menu_item)}[data-test-value="${page}"]`)
.parent()
.parent()
}
})
2 changes: 1 addition & 1 deletion cypress/support/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,5 @@ Cypress.Commands.add('logout', () => {
})

Cypress.Commands.add('waitWorkspacePageInit', () => {
cy.el(EDataTest.workspace_header_user_avatar).should('exist').and('not.be.empty')
cy.el(EDataTest.workspace_header_user_avatar, { timeout: 15000 }).should('exist').and('not.be.empty')
})
1 change: 1 addition & 0 deletions cypress/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ import { type EDataTest } from '@/enums/EDataTest'

export const elSelector = (dataTest: EDataTest) => `[data-test="${dataTest}"]`
export const withLang = (url: string = '') => `/${Cypress.env('language') || 'en'}${url}`
export const isMobile = () => Cypress.config('viewportWidth') < Cypress.env('mobileViewportWidthBreakpoint')
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"stylelint:fix": "stylelint \"src/**/*.{scss,vue}\" --fix",
"prepare": "husky install",
"test": "vitest",
"cypress:open": "cypress open"
"cypress:open": "cypress open",
"cypress:open:mobile": "cypress open --config \"{\\\"e2e\\\":{\\\"viewportWidth\\\":400,\\\"viewportHeight\\\":660}}\""
},
"lint-staged": {
"src/**/*.{scss,vue}": [
Expand Down
4 changes: 4 additions & 0 deletions src/enums/EDataTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export enum EDataTest {
workspace_content,
workspace_navigation_item,
workspace_header_user_avatar,
workspace_bottom_menu,
workspace_bottom_menu_item,

words_container_header_checkbox,
words_container_header_search,
Expand Down Expand Up @@ -42,6 +44,8 @@ export enum EDataTest {
export enum EDataTestClass {
app_notifications = 'app_notifications',

word_status = 'data-test__word_status',

words_container_header_status = 'data-test__words-container-header-status',
words_container_header_status_active = 'data-test__words-container-header-status--active',

Expand Down
1 change: 1 addition & 0 deletions src/enums/EPageName.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const enum EPageName {
LANDING = 'landing',
OFFICE = 'office',
OFFICE_PROFILE = 'office-profile',
OFFICE_SETTINGS = 'office-settings',
DICTIONARY = 'dictionary',
Expand Down
Loading