From 6cd3af34a0a5f4869305824694c913f27077cf1e Mon Sep 17 00:00:00 2001 From: Danyl Zhmyrov <33990613+ZhmenZH@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:08:05 +0300 Subject: [PATCH 01/25] Updated Google Analytics (#6589) --- apps/ngx-bootstrap-docs/src/404.html | 13 ++++------ apps/ngx-bootstrap-docs/src/index.html | 34 ++++++++++++-------------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/apps/ngx-bootstrap-docs/src/404.html b/apps/ngx-bootstrap-docs/src/404.html index 101cbe2178..b3fa8d35b2 100644 --- a/apps/ngx-bootstrap-docs/src/404.html +++ b/apps/ngx-bootstrap-docs/src/404.html @@ -33,16 +33,13 @@ + diff --git a/apps/ngx-bootstrap-docs/src/index.html b/apps/ngx-bootstrap-docs/src/index.html index 93057c9f43..bd16689bc3 100644 --- a/apps/ngx-bootstrap-docs/src/index.html +++ b/apps/ngx-bootstrap-docs/src/index.html @@ -4,7 +4,8 @@ Angular Bootstrap - + @@ -28,23 +29,20 @@ - - Loading... - - - - + - - + gtag('config', 'G-8Z0HMZ2FH4'); + + + From e2958bf490feb5ae5566449d7eada429afe100f7 Mon Sep 17 00:00:00 2001 From: Leonid Losyukov <136792732+leonidlosyukov@users.noreply.github.com> Date: Fri, 7 Jul 2023 15:58:22 +0400 Subject: [PATCH 02/25] feat: Migration to Playwright (#6590) * Playwright setup + 4 specs migrated Playwright setup * Remove Playwright from Credits * chore: sync package and lock * chore: install chromium at CI * chore: nx cloud doesn't work on CI * chore: install chromium in GA * chore: include nx cloud token * chore: install deps for full e2e --------- Co-authored-by: Dmitriy Shekhovtsov valorkin --- .github/workflows/on-push-or-pull.yml | 57 +- .gitignore | 5 + README.md | 5 +- angular.json | 39 +- apps/ngx-bootstrap-docs-e2e/.eslintrc.json | 35 +- apps/ngx-bootstrap-docs-e2e/cypress-full.json | 18 - apps/ngx-bootstrap-docs-e2e/cypress.json | 18 - .../playwright.config.ts | 30 + .../src/fixtures/example.json | 5 - .../src/full/accordion_page.spec.ts | 469 + .../src/full/accordion_page_spec.ts | 431 - .../src/full/alerts_page.spec.ts | 254 + .../src/full/alerts_page_spec.ts | 204 - .../src/integration/accordion_page.spec.ts | 74 + .../src/integration/accordion_page_spec.ts | 57 - .../src/integration/alerts_page.spec.ts | 35 + .../src/integration/alerts_page_spec.ts | 18 - .../src/integration/app.spec.ts | 1 - .../src/plugins/index.js | 26 - .../src/support/accordion.po.ts | 122 +- .../src/support/alerts.po.ts | 105 +- .../src/support/base.po.ts | 97 + .../src/support/index.ts | 18 - apps/ngx-bootstrap-docs-e2e/tsconfig.e2e.json | 15 +- apps/ngx-bootstrap-docs/src/ng-api-doc.ts | 3172 +- .../documentation.component.html | 7 - .../common/sidebar/helpers/sidebar-helpers.ts | 3 +- nx.json | 8 +- package-lock.json | 42292 +++++++++------- package.json | 16 +- src/root/README.md | 5 +- 31 files changed, 26318 insertions(+), 21323 deletions(-) delete mode 100644 apps/ngx-bootstrap-docs-e2e/cypress-full.json delete mode 100644 apps/ngx-bootstrap-docs-e2e/cypress.json create mode 100644 apps/ngx-bootstrap-docs-e2e/playwright.config.ts delete mode 100644 apps/ngx-bootstrap-docs-e2e/src/fixtures/example.json create mode 100644 apps/ngx-bootstrap-docs-e2e/src/full/accordion_page.spec.ts delete mode 100644 apps/ngx-bootstrap-docs-e2e/src/full/accordion_page_spec.ts create mode 100644 apps/ngx-bootstrap-docs-e2e/src/full/alerts_page.spec.ts delete mode 100644 apps/ngx-bootstrap-docs-e2e/src/full/alerts_page_spec.ts create mode 100644 apps/ngx-bootstrap-docs-e2e/src/integration/accordion_page.spec.ts delete mode 100644 apps/ngx-bootstrap-docs-e2e/src/integration/accordion_page_spec.ts create mode 100644 apps/ngx-bootstrap-docs-e2e/src/integration/alerts_page.spec.ts delete mode 100644 apps/ngx-bootstrap-docs-e2e/src/integration/alerts_page_spec.ts delete mode 100644 apps/ngx-bootstrap-docs-e2e/src/integration/app.spec.ts delete mode 100644 apps/ngx-bootstrap-docs-e2e/src/plugins/index.js create mode 100644 apps/ngx-bootstrap-docs-e2e/src/support/base.po.ts delete mode 100644 apps/ngx-bootstrap-docs-e2e/src/support/index.ts diff --git a/.github/workflows/on-push-or-pull.yml b/.github/workflows/on-push-or-pull.yml index 23163fd0c9..760f0e8ea1 100644 --- a/.github/workflows/on-push-or-pull.yml +++ b/.github/workflows/on-push-or-pull.yml @@ -13,9 +13,8 @@ env: MOZ_HEALESS: 1 SAUCE_USERNAME_PR: valorkinpr SAUCE_ACCESS_KEY_PR: e0a97bd3-4b74-4408-89bf-cce1b44a8bf1 - CYPRESS_CACHE_FOLDER: 'node_modules/.cypress' - CYPRESS_RECORD_KEY: 4aa7a1c0-3a4f-444e-b324-6fc305a543a8 FIREBASE_CHANNEL: ${{ fromJSON('["", "live"]')[!github.base_ref] }} + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 0 CACHE_NODE_MODULES_PATH: | ~/.npm @@ -118,21 +117,16 @@ jobs: channelId: ${{ env.FIREBASE_CHANNEL }} expires: 7d - # run cypress + # run playwright e2e_smoke: - name: e2e smoke + name: e2e smoke (${{ matrix.shard }}/${{ strategy.job-total }}) runs-on: ubuntu-latest needs: [install, build, firebase_preview] strategy: - # when one test fails, DO NOT cancel the other - # containers, because this will kill Cypress processes - # leaving the Dashboard hanging ... - # https://github.com/cypress-io/github-action/issues/48 fail-fast: false matrix: - # run 3 copies of the current job in parallel - containers: [1, 2, 3, 4, 5] + shard: [1, 2] steps: - uses: actions/checkout@v2 - uses: actions/cache@v2 @@ -144,15 +138,25 @@ jobs: path: ${{ env.CACHE_DIST_PATH }} key: dist-${{ github.run_id }} - # because of "record" and "parallel" parameters - # these containers will load balance all found tests among themselves + - name: Install playwright browsers + run: | + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npx playwright install + npx playwright install-deps chromium + - name: smoke e2e on firebase if: ${{ needs.firebase_preview.outputs.output_url }} - run: npx nx run ngx-bootstrap-docs-e2e:e2e -- --configuration firebase --runner cloud --record --group smoke --baseUrl=${{ needs.firebase_preview.outputs.output_url }}/ngx-bootstrap/ --parallel + run: npx nx run ngx-bootstrap-docs-e2e:e2e --pwProject=chromium-integration --baseUrl=${{ needs.firebase_preview.outputs.output_url }}/ngx-bootstrap/ --skipServe --shard=${{ matrix.shard }}/${{ strategy.job-total }} - name: smoke e2e local if: ${{ !needs.firebase_preview.outputs.output_url }} - run: npx nx run ngx-bootstrap-docs-e2e:e2e -- --configuration production --runner cloud --record --group smoke --parallel + run: npx nx run ngx-bootstrap-docs-e2e:e2e --pwProject=chromium-integration --shard=${{ matrix.shard }}/${{ strategy.job-total }} + + - uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright-report-${{ matrix.shard }}_${{ strategy.job-total }} + path: playwright-report + retention-days: 30 e2e_full: name: e2e full @@ -160,14 +164,9 @@ jobs: needs: [e2e_smoke] strategy: - # when one test fails, DO NOT cancel the other - # containers, because this will kill Cypress processes - # leaving the Dashboard hanging ... - # https://github.com/cypress-io/github-action/issues/48 fail-fast: false matrix: - # run 3 copies of the current job in parallel - containers: [1, 2, 3, 4, 5] + shard: [1, 2] steps: - uses: actions/checkout@v2 - uses: actions/cache@v2 @@ -179,14 +178,24 @@ jobs: path: ${{ env.CACHE_DIST_PATH }} key: dist-${{ github.run_id }} - # because of "record" and "parallel" parameters - # these containers will load balance all found tests among themselves + - name: Install playwright browsers + run: | + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npx playwright install + npx playwright install-deps chromium + - name: full e2e on firebase if: ${{ needs.firebase_preview.outputs.output_url }} continue-on-error: true - run: npx nx run ngx-bootstrap-docs-e2e:e2e -- --configuration firebase --runner cloud --cypressConfig ./apps/ngx-bootstrap-docs-e2e/cypress-full.json --record --group full --baseUrl=${{ needs.firebase_preview.outputs.output_url }}/ngx-bootstrap/ --parallel + run: npx nx run ngx-bootstrap-docs-e2e:e2e --pwProject=chromium-full --baseUrl=${{ needs.firebase_preview.outputs.output_url }}/ngx-bootstrap/ --skipServe --shard=${{ matrix.shard }}/${{ strategy.job-total }} - name: full e2e on local if: ${{ !needs.firebase_preview.outputs.output_url }} continue-on-error: true - run: npx nx run ngx-bootstrap-docs-e2e:e2e -- --configuration production --runner cloud --cypressConfig ./apps/ngx-bootstrap-docs-e2e/cypress-full.json --record --group full --parallel + run: npx nx run ngx-bootstrap-docs-e2e:e2e --pwProject=chromium-full --shard=${{ matrix.shard }}/${{ strategy.job-total }} + + - uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright-report-${{ matrix.shard }}_${{ strategy.job-total }} + path: playwright-report + retention-days: 30 diff --git a/.gitignore b/.gitignore index cd1001e74f..db2a09372e 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,8 @@ scully.log /schematics/**/*.js /schematics/**/*.js.map /schematics/**/*.d.ts + +# Playwright +**/test-results/ +**/playwright-report/ +**/playwright/.cache/ diff --git a/README.md b/README.md index 0b1d94f490..28f38b2d07 100644 --- a/README.md +++ b/README.md @@ -199,10 +199,7 @@ Please read our [contribution guidelines](https://github.com/valor-software/ngx- ### Credits Crossbrowser testing sponsored by [Saucelabs](https://saucelabs.com/) -[Saucelabs](https://saucelabs.com/) - -End-to-end testing sponsored by [Cypress](https://www.cypress.io/) -[Cypress](https://www.cypress.io/) +[Saucelabs](https://saucelabs.com/) ### License diff --git a/angular.json b/angular.json index bb0bd9e8ab..8c3537a02d 100644 --- a/angular.json +++ b/angular.json @@ -1478,16 +1478,18 @@ ] }, "ngx-bootstrap-docs-e2e": { - "$schema": "../../node_modules/nx/schemas/project-schema.json", "root": "apps/ngx-bootstrap-docs-e2e", - "sourceRoot": "apps/ngx-bootstrap-docs-e2e/src", "projectType": "application", + "sourceRoot": "apps/ngx-bootstrap-docs-e2e/src", "architect": { "e2e": { - "builder": "@nrwl/cypress:cypress", + "builder": "@nxkit/playwright:test", + "outputs": [ + "{options.outputPath}" + ], "options": { - "cypressConfig": "apps/ngx-bootstrap-docs-e2e/cypress.json", - "tsConfig": "apps/ngx-bootstrap-docs-e2e/tsconfig.e2e.json", + "outputPath": "dist/apps/ngx-bootstrap-docs-e2e/test-results", + "playwrightConfig": "apps/ngx-bootstrap-docs-e2e/playwright.config.ts", "devServerTarget": "ngx-bootstrap-docs:serve" }, "configurations": { @@ -1499,8 +1501,34 @@ } } }, + "debug": { + "builder": "@nxkit/playwright:test", + "outputs": [ + "{options.outputPath}" + ], + "options": { + "outputPath": "dist/apps/ngx-bootstrap-docs-e2e/test-results", + "playwrightConfig": "apps/ngx-bootstrap-docs-e2e/playwright.config.ts", + "devServerTarget": "ngx-bootstrap-docs:serve", + "debug": true + }, + "configurations": { + "production": { + "devServerTarget": "ngx-bootstrap-docs:serve:production" + } + } + }, + "show-report": { + "builder": "@nxkit/playwright:show-report", + "options": { + "reportPath": "dist/apps/ngx-bootstrap-docs-e2e/playwright-report" + } + }, "lint": { "builder": "@nrwl/linter:eslint", + "outputs": [ + "{options.outputFile}" + ], "options": { "lintFilePatterns": [ "apps/ngx-bootstrap-docs-e2e/**/*.{js,ts}" @@ -1508,6 +1536,7 @@ } } }, + "tags": [], "implicitDependencies": [ "ngx-bootstrap-docs" ] diff --git a/apps/ngx-bootstrap-docs-e2e/.eslintrc.json b/apps/ngx-bootstrap-docs-e2e/.eslintrc.json index 595f51e407..53132676a6 100644 --- a/apps/ngx-bootstrap-docs-e2e/.eslintrc.json +++ b/apps/ngx-bootstrap-docs-e2e/.eslintrc.json @@ -1,14 +1,33 @@ { - "extends": ["plugin:cypress/recommended", "../../.eslintrc.json"], - "ignorePatterns": ["!**/*"], - "rules": {}, + "extends": [ + "../../.eslintrc.json" + ], + "ignorePatterns": [ + "!**/*" + ], "overrides": [ { - "files": ["src/plugins/index.js"], - "rules": { - "@typescript-eslint/no-var-requires": "off", - "no-undef": "off" - } + "files": [ + "*.ts", + "*.tsx", + "*.js", + "*.jsx" + ], + "rules": {} + }, + { + "files": [ + "*.ts", + "*.tsx" + ], + "rules": {} + }, + { + "files": [ + "*.js", + "*.jsx" + ], + "rules": {} } ] } diff --git a/apps/ngx-bootstrap-docs-e2e/cypress-full.json b/apps/ngx-bootstrap-docs-e2e/cypress-full.json deleted file mode 100644 index 80dcc58e9d..0000000000 --- a/apps/ngx-bootstrap-docs-e2e/cypress-full.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "baseUrl": "http://localhost:4200/#/", - "projectId": "5mm2dy", - "fileServerFolder": ".", - "fixturesFolder": "./src/fixtures", - "integrationFolder": "./src/full", - "modifyObstructiveCode": false, - "pluginsFile": "./src/plugins/index", - "supportFile": "./src/support/index.ts", - "video": true, - "parallel": true, - "videosFolder": "../../dist/cypress/apps/ngx-bootstrap-docs-e2e/videos", - "screenshotsFolder": "../../dist/cypress/apps/ngx-bootstrap-docs-e2e/screenshots", - "chromeWebSecurity": false, - "responseTimeout": 60000, - "pageLoadTimeout": 120000, - "scrollBehavior": "center" -} diff --git a/apps/ngx-bootstrap-docs-e2e/cypress.json b/apps/ngx-bootstrap-docs-e2e/cypress.json deleted file mode 100644 index 405e59e567..0000000000 --- a/apps/ngx-bootstrap-docs-e2e/cypress.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "baseUrl": "http://127.0.0.1/#/", - "projectId": "5mm2dy", - "fileServerFolder": ".", - "fixturesFolder": "./src/fixtures", - "integrationFolder": "./src/integration", - "modifyObstructiveCode": false, - "pluginsFile": "./src/plugins/index", - "supportFile": "./src/support/index.ts", - "video": true, - "parallel": true, - "videosFolder": "../../dist/cypress/apps/ngx-bootstrap-docs-e2e/videos", - "screenshotsFolder": "../../dist/cypress/apps/ngx-bootstrap-docs-e2e/screenshots", - "chromeWebSecurity": false, - "responseTimeout": 60000, - "pageLoadTimeout": 120000, - "scrollBehavior": "center" -} diff --git a/apps/ngx-bootstrap-docs-e2e/playwright.config.ts b/apps/ngx-bootstrap-docs-e2e/playwright.config.ts new file mode 100644 index 0000000000..3ec9936a6a --- /dev/null +++ b/apps/ngx-bootstrap-docs-e2e/playwright.config.ts @@ -0,0 +1,30 @@ +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + testMatch: '**/*.spec.ts', + fullyParallel: true, + workers: 3, + reporter: [['html', { outputFolder: 'playwright-report', open: 'never' }]], + use: { + baseURL: 'http://localhost:4200/ngx-bootstrap/', + headless: true + }, + + projects: [ + { + name: 'chromium-integration', + use: { ...devices['Desktop Chrome'] }, + testDir: './src/integration' + }, + { + name: 'chromium-full', + use: { ...devices['Desktop Chrome'] }, + testDir: './src/full' + }, + { + name: 'chromium-all', + use: { ...devices['Desktop Chrome'] }, + testDir: './src' + } + ], +}); diff --git a/apps/ngx-bootstrap-docs-e2e/src/fixtures/example.json b/apps/ngx-bootstrap-docs-e2e/src/fixtures/example.json deleted file mode 100644 index 02e4254378..0000000000 --- a/apps/ngx-bootstrap-docs-e2e/src/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} diff --git a/apps/ngx-bootstrap-docs-e2e/src/full/accordion_page.spec.ts b/apps/ngx-bootstrap-docs-e2e/src/full/accordion_page.spec.ts new file mode 100644 index 0000000000..ff5f9092d9 --- /dev/null +++ b/apps/ngx-bootstrap-docs-e2e/src/full/accordion_page.spec.ts @@ -0,0 +1,469 @@ +import { test as base } from '@playwright/test'; +import { AccordionPo } from '../support/accordion.po'; + +const test = base.extend<{ accordionPo: AccordionPo }>({ + accordionPo: async ({ page }, use) => { + const accordionPo = new AccordionPo(page); + await use(accordionPo); + }, +}); + +test.describe('Accordion page testing suite', () => { + let tabName: string; + let tabSelector: string; + + test.beforeEach(async ({ accordionPo }) => { + tabName = 'Overview'; + tabSelector = `tab[heading="${tabName}"]`; + await accordionPo.navigateTo(); + }); + + test.describe('Group opening event', () => { + let groupOpenEvent: string; + + test.beforeEach(async ({ accordionPo }) => { + groupOpenEvent = tabSelector + accordionPo.exampleDemosArr.openEvent; + await accordionPo.scrollToMenu('Group opening event'); + }); + + test('example contains 3 accordion items, initially not expanded', async ({ accordionPo }) => { + await accordionPo.expectAccordionGroupCountEqual(groupOpenEvent, 3); + await accordionPo.expectAccordionItemExpanded(groupOpenEvent, 0, false); + await accordionPo.expectAccordionItemExpanded(groupOpenEvent, 1, false); + await accordionPo.expectAccordionItemExpanded(groupOpenEvent, 2, false); + await accordionPo.expectItemContentVisible(groupOpenEvent, 0, false); + await accordionPo.expectItemContentVisible(groupOpenEvent, 1, false); + await accordionPo.expectItemContentVisible(groupOpenEvent, 2, false); + }); + + test(`when user click on item without event listener, item opened, in the browser console - nothing happens + after click on item again, it closes and in the browser console - nothing happens`, async ({ accordionPo }) => { + const consoleMessages = await accordionPo.getConsoleLogs(); + await accordionPo.clickOnAccordionGroup(groupOpenEvent, 0); + await accordionPo.expectAccordionItemExpanded(groupOpenEvent, 0, true); + await accordionPo.expectItemContentVisible(groupOpenEvent, 0, true); + await accordionPo.expectConsoleLogCalled(consoleMessages, false); + await accordionPo.clickOnAccordionGroup(groupOpenEvent, 0); + await accordionPo.expectAccordionItemExpanded(groupOpenEvent, 0, false); + await accordionPo.expectItemContentVisible(groupOpenEvent, 0, false); + await accordionPo.expectConsoleLogCalled(consoleMessages, false); + }); + + test(`when user click on item with event listener, it opens and in the console - "Accordion has been opened"`, async({ accordionPo }) => { + const openLog = 'Accordion has been opened'; + const consoleMessages = await accordionPo.getConsoleLogs(); + await accordionPo.expectConsoleLogCalled(consoleMessages, false); + await accordionPo.clickOnAccordionGroup(groupOpenEvent, 1); + await accordionPo.expectAccordionItemExpanded(groupOpenEvent, 1, true); + await accordionPo.expectItemContentVisible(groupOpenEvent, 1, true); + await accordionPo.expectConsoleLogCalled(consoleMessages, true, openLog); + }); + + test(`when user click on item again, it closes and in the console - "Accordion has been closed"`, async ({ accordionPo }) => { + const closeLog = 'Accordion has been closed'; + await accordionPo.clickOnAccordionGroup(groupOpenEvent, 1); + await accordionPo.expectAccordionItemExpanded(groupOpenEvent, 1, true); + await accordionPo.expectItemContentVisible(groupOpenEvent, 1, true); + const consoleMessages = await accordionPo.getConsoleLogs(); + await accordionPo.clickOnAccordionGroup(groupOpenEvent, 1); + await accordionPo.expectAccordionItemExpanded(groupOpenEvent, 1, false); + await accordionPo.expectItemContentVisible(groupOpenEvent, 1, false); + await accordionPo.expectConsoleLogCalled(consoleMessages, true, closeLog); + }); + }); + + test.describe('Custom HTML', () => { + let customHTML: string; + + test.beforeEach(async ({ accordionPo }) => { + customHTML = tabSelector + accordionPo.exampleDemosArr.customHtml; + await accordionPo.scrollToMenu('Custom HTML'); + }); + + test(`example contains 2 accordion items, initially not expanded, 1st have span with "Some HTML here" text, + second item don't have any additional html with closed state`, async({ accordionPo }) => { + await accordionPo.expectAccordionGroupCountEqual(customHTML, 2); + await accordionPo.expectAccordionItemExpanded(customHTML, 0, false); + await accordionPo.expectAccordionItemExpanded(customHTML, 1, false); + await accordionPo.expectItemContentVisible(customHTML, 0, false); + await accordionPo.expectItemContentVisible(customHTML, 1, false); + await accordionPo.expectAccordionItemContainTxt(customHTML, accordionPo.additionalHtml, 0, 'Some HTML here', true); + await accordionPo.expectAccordionItemContainTxt(customHTML, accordionPo.additionalHtml, 1, 'And some HTML here', false); + }); + + test(`when user click on the first item, it is opened and content shown + after second click on item it is closed`, async({ accordionPo }) => { + await accordionPo.clickOnAccordionGroup(customHTML, 0); + await accordionPo.expectAccordionItemExpanded(customHTML, 0, true); + await accordionPo.expectAccordionItemExpanded(customHTML, 1, false); + await accordionPo.expectItemContentVisible(customHTML, 0, true); + await accordionPo.expectItemContentVisible(customHTML, 1, false); + await accordionPo.clickOnAccordionGroup(customHTML, 0); + await accordionPo.expectAccordionItemExpanded(customHTML, 0, false); + }); + + test(`when user click on the second item, it is opened and there is a span with "And some HTML here" + after second click on item it is closed`, async({ accordionPo }) => { + await accordionPo.clickOnAccordionGroup(customHTML, 1); + await accordionPo.expectAccordionItemExpanded(customHTML, 1, true); + await accordionPo.expectAccordionItemExpanded(customHTML, 0, false); + await accordionPo.expectItemContentVisible(customHTML, 1, true); + await accordionPo.expectItemContentVisible(customHTML, 0, false); + await accordionPo.expectAccordionItemContainTxt(customHTML, accordionPo.additionalHtml, 1, 'And some HTML here', true); + await accordionPo.clickOnAccordionGroup(customHTML, 1); + await accordionPo.expectAccordionItemExpanded(customHTML, 1, false); + }); + }); + + test.describe('Disabled', () => { + let disabled: string; + + test.beforeEach(async ({ accordionPo }) => { + disabled = tabSelector + accordionPo.exampleDemosArr.disabled; + await accordionPo.scrollToMenu('Disabled'); + }); + + test(`example contains 3 accordion items, initially not expanded and btn "Enable / Disable first panel"`, async({ accordionPo }) => { + await accordionPo.expectAccordionGroupCountEqual(disabled, 3); + await accordionPo.expectAccordionItemExpanded(disabled, 0, false); + await accordionPo.expectAccordionItemExpanded(disabled, 1, false); + await accordionPo.expectAccordionItemExpanded(disabled, 2, false); + await accordionPo.expectItemContentVisible(disabled, 0, false); + await accordionPo.expectItemContentVisible(disabled, 1, false); + await accordionPo.expectItemContentVisible(disabled, 2, false); + await accordionPo.expectBtnTxtEqual(disabled, ' Enable / Disable first panel '); + }); + + test('when user click on "Enable/Disable first panel" button then the first item is not clickable', async({ accordionPo }) => { + await accordionPo.clickOnBtn(disabled); + await accordionPo.clickOnAccordionGroup(disabled, 0); + await accordionPo.expectAccordionItemExpanded(disabled, 0, false); + }); + + test(`when user click on "Enable/Disable first panel" second time + and click on first item, then item opened and user see content`, async({ accordionPo }) => { + await accordionPo.clickOnBtn(disabled); + await accordionPo.clickOnBtn(disabled); + await accordionPo.clickOnAccordionGroup(disabled, 0); + await accordionPo.expectAccordionItemExpanded(disabled, 0, true); + await accordionPo.expectItemContentVisible(disabled, 0, true); + }); + + test('when user click on "Enable/Disable first panel" third time then the first item is not clickable again', async({ accordionPo }) => { + await accordionPo.clickOnBtn(disabled); + await accordionPo.clickOnBtn(disabled); + await accordionPo.clickOnBtn(disabled); + await accordionPo.clickOnAccordionGroup(disabled, 0); + await accordionPo.expectAccordionItemExpanded(disabled, 0, false); + await accordionPo.expectItemContentVisible(disabled, 0, false); + }); + + test('when user click on 2d and 3d item, they open and content inside shown', async({ accordionPo }) => { + await accordionPo.clickOnAccordionGroup(disabled, 1); + await accordionPo.clickOnAccordionGroup(disabled, 2); + await accordionPo.expectAccordionItemExpanded(disabled, 1, true); + await accordionPo.expectAccordionItemExpanded(disabled, 2, true); + await accordionPo.expectItemContentVisible(disabled, 1, true); + await accordionPo.expectItemContentVisible(disabled, 2, true); + }); + }); + + test.describe('Initially opened', () => { + let initiallyOpened: string; + + test.beforeEach(async ({ accordionPo }) => { + initiallyOpened = tabSelector + accordionPo.exampleDemosArr.initiallyOpened; + await accordionPo.scrollToMenu('Initially opened'); + }); + + test(`example contains 3 accordion items, 2d initially expanded, other - not`, async({ accordionPo }) => { + await accordionPo.expectAccordionGroupCountEqual(initiallyOpened, 3); + await accordionPo.expectAccordionItemExpanded(initiallyOpened, 0, false); + await accordionPo.expectAccordionItemExpanded(initiallyOpened, 1, true); + await accordionPo.expectAccordionItemExpanded(initiallyOpened, 2, false); + await accordionPo.expectItemContentVisible(initiallyOpened, 0, false); + await accordionPo.expectItemContentVisible(initiallyOpened, 1, true); + await accordionPo.expectItemContentVisible(initiallyOpened, 2, false); + }); + + test('when user click on 2d item, it should be closed', async({ accordionPo }) => { + await accordionPo.clickOnAccordionGroup(initiallyOpened, 1); + await accordionPo.expectAccordionItemExpanded(initiallyOpened, 1, false); + await accordionPo.expectItemContentVisible(initiallyOpened, 1, false); + }); + + test('when user click on 1t or 3d item, it should be opened', async({ accordionPo }) => { + await accordionPo.clickOnAccordionGroup(initiallyOpened, 0); + await accordionPo.clickOnAccordionGroup(initiallyOpened, 2); + await accordionPo.expectAccordionItemExpanded(initiallyOpened, 0, true); + await accordionPo.expectAccordionItemExpanded(initiallyOpened, 2, true); + await accordionPo.expectItemContentVisible(initiallyOpened, 0, true); + await accordionPo.expectItemContentVisible(initiallyOpened, 2, true); + }); + + test('when user click on 2d item, it should be closed, after reload page, it become expanded', async({ accordionPo, page }) => { + await accordionPo.clickOnAccordionGroup(initiallyOpened, 1); + await accordionPo.expectAccordionItemExpanded(initiallyOpened, 1, false); + await accordionPo.expectItemContentVisible(initiallyOpened, 1, false); + await page.reload(); + await accordionPo.expectAccordionItemExpanded(initiallyOpened, 1, true); + await accordionPo.expectItemContentVisible(initiallyOpened, 1, true); + }); + }); + + test.describe('Dynamic accordion', () => { + let dynamicAccordion: string; + + test.beforeEach(async ({ accordionPo }) => { + dynamicAccordion = tabSelector + accordionPo.exampleDemosArr.dynamicAccordion; + await accordionPo.scrollToMenu('Dynamic accordion'); + }); + + test(`example contains 2 accordion items, initially not expanded and button "Add Group Item"`, async({ accordionPo }) => { + await accordionPo.expectAccordionGroupCountEqual(dynamicAccordion, 2); + await accordionPo.expectAccordionItemExpanded(dynamicAccordion, 0, false); + await accordionPo.expectAccordionItemExpanded(dynamicAccordion, 1, false); + await accordionPo.expectItemContentVisible(dynamicAccordion, 0, false); + await accordionPo.expectItemContentVisible(dynamicAccordion, 1, false); + await accordionPo.expectBtnTxtEqual(dynamicAccordion, ' Add Group Item '); + }); + + test(`when user click on each item, it opens and content inside shown`, async({ accordionPo }) => { + await accordionPo.clickOnAccordionGroup(dynamicAccordion, 0); + await accordionPo.clickOnAccordionGroup(dynamicAccordion, 1); + await accordionPo.expectAccordionItemExpanded(dynamicAccordion, 0, true); + await accordionPo.expectAccordionItemExpanded(dynamicAccordion, 1, true); + await accordionPo.expectItemContentVisible(dynamicAccordion, 0, true); + await accordionPo.expectItemContentVisible(dynamicAccordion, 1, true); + }); + + test(`when user click on "Add Group Item" button then new item added, + when user click on just added new item, then shown content inside`, async({ accordionPo }) => { + await accordionPo.clickOnBtn(dynamicAccordion); + await accordionPo.expectAccordionGroupCountEqual(dynamicAccordion, 3); + await accordionPo.expectAccordionItemExpanded(dynamicAccordion, 2, false); + await accordionPo.expectItemContentVisible(dynamicAccordion, 2, false); + await accordionPo.clickOnAccordionGroup(dynamicAccordion, 2); + await accordionPo.expectAccordionItemExpanded(dynamicAccordion, 2, true); + await accordionPo.expectItemContentVisible(dynamicAccordion, 2, true); + }); + + test(`when user click on "Add Group Item" N times, the amount of items increased on N + when user reload page, amount of items in Accordion dynamic block should be 2`, async({ accordionPo, page }) => { + await accordionPo.clickOnBtn(dynamicAccordion); + await accordionPo.clickOnBtn(dynamicAccordion); + await accordionPo.clickOnBtn(dynamicAccordion); + await accordionPo.clickOnBtn(dynamicAccordion); + await accordionPo.expectAccordionGroupCountEqual(dynamicAccordion, 6); + await page.reload(); + await accordionPo.expectAccordionGroupCountEqual(dynamicAccordion, 2); + }); + }); + + test.describe('Dynamic body content', () => { + let dynamicBody: string; + const itemBody = '.panel-body'; + + test.beforeEach(async ({ accordionPo }) => { + dynamicBody = tabSelector + accordionPo.exampleDemosArr.dynamicBody; + await accordionPo.scrollToMenu('Dynamic body content'); + }); + + test(`example contains 3 accordion items, initially not expanded`, async({ accordionPo }) => { + await accordionPo.expectAccordionGroupCountEqual(dynamicBody, 3); + await accordionPo.expectAccordionItemExpanded(dynamicBody, 0, false); + await accordionPo.expectAccordionItemExpanded(dynamicBody, 1, false); + await accordionPo.expectAccordionItemExpanded(dynamicBody, 2, false); + await accordionPo.expectItemContentVisible(dynamicBody, 0, false); + await accordionPo.expectItemContentVisible(dynamicBody, 1, false); + await accordionPo.expectItemContentVisible(dynamicBody, 2, false); + }); + + test(`when user click on 1st item, then user see "Add Item" button, there is 3 div-blocks`, async({ accordionPo }) => { + await accordionPo.clickOnAccordionGroup(dynamicBody, 0); + await accordionPo.expectAccordionItemExpanded(dynamicBody, 0, true); + await accordionPo.expectItemContentVisible(dynamicBody, 0, true); + await accordionPo.expectBtnExist(dynamicBody, 'Add Item ', 1); + await accordionPo.expectAccordionItemContainTxt(dynamicBody, '.panel-body', 0, 'Item 1Item 2Item 3', true); + }); + + test(`when user click on "Add Item" button, amount of div-blocks inside should be increased to 4, + when click on "Add Item" again, amount of div-blocks inside should be increased to 5`, async({ accordionPo }) => { + await accordionPo.clickOnAccordionGroup(dynamicBody, 0); + await accordionPo.clickOnBtn(dynamicBody, 1); + await accordionPo.expectAccordionItemContainTxt(dynamicBody, itemBody, 0, 'Item 1Item 2Item 3Item 4', true); + await accordionPo.clickOnBtn(dynamicBody, 1); + await accordionPo.expectAccordionItemContainTxt(dynamicBody, itemBody, 0, 'Item 1Item 2Item 3Item 4Item 5', true); + await accordionPo.clickOnBtn(dynamicBody, 1); + await accordionPo.expectAccordionItemContainTxt(dynamicBody, itemBody, 0, 'Item 1Item 2Item 3Item 4Item 5Item 6', true); + }); + + test(`when user click on "Add Item" button a few times, and then reload page, + then amount of items should back to default (3 items and 3 div-blocks inside first item)`, async({ accordionPo, page }) => { + await accordionPo.clickOnAccordionGroup(dynamicBody, 0); + await accordionPo.clickOnBtn(dynamicBody, 1); + await accordionPo.clickOnBtn(dynamicBody, 1); + await accordionPo.expectAccordionItemExpanded(dynamicBody, 0, true); + await accordionPo.expectAccordionItemContainTxt(dynamicBody, itemBody, 0, 'Item 1Item 2Item 3Item 4Item 5', true); + await page.reload(); + await accordionPo.expectAccordionItemExpanded(dynamicBody, 0, false); + await accordionPo.clickOnAccordionGroup(dynamicBody, 0); + await accordionPo.expectAccordionItemExpanded(dynamicBody, 0, true); + await accordionPo.expectAccordionItemContainTxt(dynamicBody, itemBody, 0, 'Item 1Item 2Item 3', true); + }); + }); + + test.describe('Manual toggle', () => { + let manualToggle: string; + + test.beforeEach(async ({ accordionPo }) => { + manualToggle = tabSelector + accordionPo.exampleDemosArr.manualToggle; + await accordionPo.scrollToMenu('Manual toggle'); + }); + + test(`example contains 3 accordion items, only 3d initially expanded and 1 button "Toggle last panel"`, async({ accordionPo }) => { + await accordionPo.expectAccordionGroupCountEqual(manualToggle, 3); + await accordionPo.expectAccordionItemExpanded(manualToggle, 0, false); + await accordionPo.expectAccordionItemExpanded(manualToggle, 1, false); + await accordionPo.expectAccordionItemExpanded(manualToggle, 2, true); + await accordionPo.expectItemContentVisible(manualToggle, 0, false); + await accordionPo.expectItemContentVisible(manualToggle, 1, false); + await accordionPo.expectItemContentVisible(manualToggle, 2, true); + await accordionPo.expectBtnTxtEqual(manualToggle, 'Toggle last panel '); + }); + + test('when user click on "Toggle last panel" button, then last item closed and user see content inside', async({ accordionPo }) => { + await accordionPo.clickOnBtn(manualToggle); + await accordionPo.expectAccordionItemExpanded(manualToggle, 2, false); + await accordionPo.expectItemContentVisible(manualToggle, 2, false); + }); + + test('when user click on "Toggle last panel" button second time, then last item opened again', async({ accordionPo }) => { + await accordionPo.clickOnBtn(manualToggle); + await accordionPo.clickOnBtn(manualToggle); + await accordionPo.expectAccordionItemExpanded(manualToggle, 2, true); + await accordionPo.expectItemContentVisible(manualToggle, 2, true); + }); + }); + + test.describe('Open only one at a time', () => { + let oneAtATime: string; + + test.beforeEach(async ({ accordionPo }) => { + oneAtATime = tabSelector + accordionPo.exampleDemosArr.oneAtATime; + await accordionPo.scrollToMenu('Open only one at a time'); + }); + + test(`example contains 3 accordion items, initially not expanded and 1 checkbox "Open only one at a time"`, async({ accordionPo }) => { + await accordionPo.expectAccordionGroupCountEqual(oneAtATime, 3); + await accordionPo.expectAccordionItemExpanded(oneAtATime, 0, false); + await accordionPo.expectAccordionItemExpanded(oneAtATime, 1, false); + await accordionPo.expectAccordionItemExpanded(oneAtATime, 2, false); + await accordionPo.expectItemContentVisible(oneAtATime, 0, false); + await accordionPo.expectItemContentVisible(oneAtATime, 1, false); + await accordionPo.expectItemContentVisible(oneAtATime, 2, false); + await accordionPo.expectLabelTxtEqual(oneAtATime, ' Open only one at a time '); + }); + + test(`when user click on 1st item, it opened, when user click on 2d item, it opened and 1st is closed + when user click on 3d item, it opened and 2d is closed`, async({ accordionPo }) => { + await accordionPo.clickOnAccordionGroup(oneAtATime, 0); + await accordionPo.expectAccordionItemExpanded(oneAtATime, 0, true); + await accordionPo.expectAccordionItemExpanded(oneAtATime, 1, false); + await accordionPo.expectAccordionItemExpanded(oneAtATime, 2, false); + await accordionPo.clickOnAccordionGroup(oneAtATime, 1); + await accordionPo.expectItemContentVisible(oneAtATime, 0, false); + await accordionPo.expectItemContentVisible(oneAtATime, 1, true); + await accordionPo.expectItemContentVisible(oneAtATime, 2, false); + await accordionPo.clickOnAccordionGroup(oneAtATime, 2); + await accordionPo.expectItemContentVisible(oneAtATime, 0, false); + await accordionPo.expectItemContentVisible(oneAtATime, 1, false); + await accordionPo.expectItemContentVisible(oneAtATime, 2, true); + }); + + test(`when user uncheck the check-box, then after click on each item, it stay opened`, async({ accordionPo }) => { + await accordionPo.setCheckboxState(oneAtATime, false); + await accordionPo.clickOnAccordionGroup(oneAtATime, 0); + await accordionPo.clickOnAccordionGroup(oneAtATime, 1); + await accordionPo.clickOnAccordionGroup(oneAtATime, 2); + await accordionPo.expectAccordionItemExpanded(oneAtATime, 0, true); + await accordionPo.expectAccordionItemExpanded(oneAtATime, 1, true); + await accordionPo.expectAccordionItemExpanded(oneAtATime, 2, true); + }); + }); + + test.describe('Styling', () => { + let styling: string; + + test.beforeEach(async ({ accordionPo }) => { + styling = tabSelector + accordionPo.exampleDemosArr.styling; + await accordionPo.scrollToMenu('Styling'); + }); + + test(`example contains 3 accordion items, only 1st initially expanded`, async({ accordionPo }) => { + await accordionPo.expectAccordionGroupCountEqual(styling, 3); + await accordionPo.expectAccordionItemExpanded(styling, 0, true); + await accordionPo.expectAccordionItemExpanded(styling, 1, false); + await accordionPo.expectAccordionItemExpanded(styling, 2, false); + await accordionPo.expectItemContentVisible(styling, 0, true); + await accordionPo.expectItemContentVisible(styling, 1, false); + await accordionPo.expectItemContentVisible(styling, 2, false); + }); + + test(`styles for the 1st and 3d items and it content should be the same (from the customClass styles) + styling for the 2d item and content should be default`, async({ accordionPo }) => { + const colors = [ + 'rgb(91, 192, 222)', // light blue (malibu) + 'rgb(255, 255, 255)', // white + 'rgb(51, 122, 167)', // dark blue (lochmara) + 'rgb(33, 37, 41)', // grey + 'rgba(0, 0, 0, 0)' // black + ]; + await accordionPo.expectAccordionItemHaveCorrectStyle(styling, 0, colors[0], colors[1]); + await accordionPo.expectAccordionBodyHaveCorrectStyle(styling, 0, colors[2], colors[1]); + await accordionPo.expectAccordionItemHaveCorrectStyle(styling, 2, colors[0], colors[1]); + await accordionPo.expectAccordionBodyHaveCorrectStyle(styling, 2, colors[2], colors[1]); + await accordionPo.expectAccordionItemHaveCorrectStyle(styling, 1, colors[1], colors[3]); + await accordionPo.expectAccordionBodyHaveCorrectStyle(styling, 1, colors[4], colors[3]); + }); + }); + + test.describe('Configuring defaults', () => { + let configDefaults: string; + + test.beforeEach(async ({ accordionPo, page }) => { + configDefaults = accordionPo.exampleDemosArr.config; + await page.setViewportSize({ width: 1440, height: 900 }); + await accordionPo.scrollToMenu('Configuring defaults'); + }); + + test(`example contains 3 accordion items, initially not expanded + src of component contains info how to override AccordionConfig`, async({ accordionPo }) => { + await accordionPo.expectAccordionGroupCountEqual(configDefaults, 3); + await accordionPo.expectAccordionItemExpanded(configDefaults, 0, false); + await accordionPo.expectAccordionItemExpanded(configDefaults, 1, false); + await accordionPo.expectAccordionItemExpanded(configDefaults, 2, false); + await accordionPo.expectItemContentVisible(configDefaults, 0, false); + await accordionPo.expectItemContentVisible(configDefaults, 1, false); + await accordionPo.expectItemContentVisible(configDefaults, 2, false); + await accordionPo.expectComponentSrcContain('Configuring defaults', 'provide: AccordionConfig'); + await accordionPo.expectComponentSrcContain('Configuring defaults', 'closeOthers: true'); + }); + + test(`when user click on 1st item, it opened, when user click on 2d item, it opened and 1st is closed + when user click on 3d item, it opened and 2d is closed`, async({ accordionPo }) => { + await accordionPo.clickOnAccordionGroup(configDefaults, 0); + await accordionPo.expectAccordionItemExpanded(configDefaults, 0, true); + await accordionPo.expectAccordionItemExpanded(configDefaults, 1, false); + await accordionPo.expectAccordionItemExpanded(configDefaults, 2, false); + await accordionPo.clickOnAccordionGroup(configDefaults, 1); + await accordionPo.expectItemContentVisible(configDefaults, 0, false); + await accordionPo.expectItemContentVisible(configDefaults, 1, true); + await accordionPo.expectItemContentVisible(configDefaults, 2, false); + await accordionPo.clickOnAccordionGroup(configDefaults, 2); + await accordionPo.expectItemContentVisible(configDefaults, 0, false); + await accordionPo.expectItemContentVisible(configDefaults, 1, false); + await accordionPo.expectItemContentVisible(configDefaults, 2, true); + }); + }); +}); diff --git a/apps/ngx-bootstrap-docs-e2e/src/full/accordion_page_spec.ts b/apps/ngx-bootstrap-docs-e2e/src/full/accordion_page_spec.ts deleted file mode 100644 index a0c86fc5f3..0000000000 --- a/apps/ngx-bootstrap-docs-e2e/src/full/accordion_page_spec.ts +++ /dev/null @@ -1,431 +0,0 @@ -import { AccordionPo } from '../support/accordion.po'; - -describe('Accordion page testing suite', () => { - const accordion = new AccordionPo(); - - beforeEach(() => accordion.navigateTo()); - - describe('Group opening event', () => { - const groupOpenEvent = accordion.exampleDemosArr.openEvent; - - beforeEach(() => accordion.scrollToMenu('Group opening event')); - - it(`example contains 3 accordion items, initially not expanded`, () => { - accordion.isAccordionLengthEqual(groupOpenEvent, 3); - accordion.isAccordionItemExpanded(groupOpenEvent, 0, false); - accordion.isAccordionItemExpanded(groupOpenEvent, 1, false); - accordion.isAccordionItemExpanded(groupOpenEvent, 2, false); - accordion.isItemContentVisible(groupOpenEvent, 0, false); - accordion.isItemContentVisible(groupOpenEvent, 1, false); - accordion.isItemContentVisible(groupOpenEvent, 2, false); - }); - - it(`when user click on item without event listener, item opened, in the browser console - nothing happens - after click on item again, it closes and in the browser console - nothing happens`, () => { - accordion.createBrowserLogSpy().then(consoleSpy => { - accordion.clickOnAccordionGroup(groupOpenEvent, 0); - accordion.isAccordionItemExpanded(groupOpenEvent, 0, true); - accordion.isItemContentVisible(groupOpenEvent, 0, true); - accordion.isConsoleLogCalled(consoleSpy, false); - accordion.clickOnAccordionGroup(groupOpenEvent, 0); - accordion.isAccordionItemExpanded(groupOpenEvent, 0, false); - accordion.isItemContentVisible(groupOpenEvent, 0, false); - accordion.isConsoleLogCalled(consoleSpy, false); - }); - }); - - it(`when user click on item with event listener, it opens and in the console - "Accordion has been opened"`, () => { - const openLog = 'Accordion has been opened'; - accordion.createBrowserLogSpy().then(consoleSpy => { - accordion.isConsoleLogCalled(consoleSpy, false); - accordion.clickOnAccordionGroup(groupOpenEvent, 1); - accordion.isAccordionItemExpanded(groupOpenEvent, 1, true); - accordion.isItemContentVisible(groupOpenEvent, 1, true); - accordion.isConsoleLogCalled(consoleSpy, true, openLog); - }); - }); - - it(`when user click on item again, it closes and in the console - "Accordion has been closed"`, () => { - const closeLog = 'Accordion has been closed'; - accordion.clickOnAccordionGroup(groupOpenEvent, 1); - accordion.isAccordionItemExpanded(groupOpenEvent, 1, true); - accordion.isItemContentVisible(groupOpenEvent, 1, true); - accordion.createBrowserLogSpy().then(consoleSpy => { - accordion.clickOnAccordionGroup(groupOpenEvent, 1); - accordion.isAccordionItemExpanded(groupOpenEvent, 1, false); - accordion.isItemContentVisible(groupOpenEvent, 1, false); - accordion.isConsoleLogCalled(consoleSpy, true, closeLog); - }); - }); - }); - - describe('Custom HTML', () => { - const customHTML = accordion.exampleDemosArr.customHtml; - - beforeEach(() => accordion.scrollToMenu('Custom HTML')); - - it(`example contains 2 accordion items, initially not expanded, 1st have span with "Some HTML here" text, - second item don't have any additional html with closed state`, () => { - accordion.isAccordionLengthEqual(customHTML, 2); - accordion.isAccordionItemExpanded(customHTML, 0, false); - accordion.isAccordionItemExpanded(customHTML, 1, false); - accordion.isItemContentVisible(customHTML, 0, false); - accordion.isItemContentVisible(customHTML, 1, false); - accordion.isAccordionItemContain(customHTML, accordion.additionalHtml, 0, 'Some HTML here', true); - accordion.isAccordionItemContain(customHTML, accordion.additionalHtml, 1, 'And some HTML here', false); - }); - - it(`when user click on the first item, it is opened and content shown - after second click on item it is closed`, () => { - accordion.clickOnAccordionGroup(customHTML, 0); - accordion.isAccordionItemExpanded(customHTML, 0, true); - accordion.isAccordionItemExpanded(customHTML, 1, false); - accordion.isItemContentVisible(customHTML, 0, true); - accordion.isItemContentVisible(customHTML, 1, false); - accordion.clickOnAccordionGroup(customHTML, 0); - accordion.isAccordionItemExpanded(customHTML, 0, false); - }); - - it(`when user click on the second item, it is opened and there is a span with "And some HTML here" - after second click on item it is closed`, () => { - accordion.clickOnAccordionGroup(customHTML, 1); - accordion.isAccordionItemExpanded(customHTML, 1, true); - accordion.isAccordionItemExpanded(customHTML, 0, false); - accordion.isItemContentVisible(customHTML, 1, true); - accordion.isItemContentVisible(customHTML, 0, false); - accordion.isAccordionItemContain(customHTML, accordion.additionalHtml, 1, 'And some HTML here', true); - accordion.clickOnAccordionGroup(customHTML, 1); - accordion.isAccordionItemExpanded(customHTML, 1, false); - }); - }); - - describe('Disabled', () => { - const disabled = accordion.exampleDemosArr.disabled; - - beforeEach(() => accordion.scrollToMenu('Disabled')); - - it(`example contains 3 accordion items, initially not expanded and btn "Enable / Disable first panel"`, () => { - accordion.isAccordionLengthEqual(disabled, 3); - accordion.isAccordionItemExpanded(disabled, 0, false); - accordion.isAccordionItemExpanded(disabled, 1, false); - accordion.isAccordionItemExpanded(disabled, 2, false); - accordion.isItemContentVisible(disabled, 0, false); - accordion.isItemContentVisible(disabled, 1, false); - accordion.isItemContentVisible(disabled, 2, false); - accordion.isBtnTxtEqual(disabled, ' Enable / Disable first panel '); - }); - - it('when user click on "Enable/Disable first panel" button then the first item is not clickable', () => { - accordion.clickOnBtn(disabled); - accordion.clickOnAccordionGroup(disabled, 0); - accordion.isAccordionItemExpanded(disabled, 0, false); - }); - - it(`when user click on "Enable/Disable first panel" second time - and click on first item, then item opened and user see content`, () => { - accordion.clickOnBtn(disabled); - accordion.clickOnBtn(disabled); - accordion.clickOnAccordionGroup(disabled, 0); - accordion.isAccordionItemExpanded(disabled, 0, true); - accordion.isItemContentVisible(disabled, 0, true); - }); - - it('when user click on "Enable/Disable first panel" third time then the first item is not clickable again', () => { - accordion.clickOnBtn(disabled); - accordion.clickOnBtn(disabled); - accordion.clickOnBtn(disabled); - accordion.clickOnAccordionGroup(disabled, 0); - accordion.isAccordionItemExpanded(disabled, 0, false); - accordion.isItemContentVisible(disabled, 0, false); - }); - - it('when user click on 2d and 3d item, they open and content inside shown', () => { - accordion.clickOnAccordionGroup(disabled, 1); - accordion.clickOnAccordionGroup(disabled, 2); - accordion.isAccordionItemExpanded(disabled, 1, true); - accordion.isAccordionItemExpanded(disabled, 2, true); - accordion.isItemContentVisible(disabled, 1, true); - accordion.isItemContentVisible(disabled, 2, true); - }); - }); - - describe('Initially opened', () => { - const initiallyOpened = accordion.exampleDemosArr.initiallyOpened; - - beforeEach(() => accordion.scrollToMenu('Initially opened')); - - it(`example contains 3 accordion items, 2d initially expanded, other - not`, () => { - accordion.isAccordionLengthEqual(initiallyOpened, 3); - accordion.isAccordionItemExpanded(initiallyOpened, 0, false); - accordion.isAccordionItemExpanded(initiallyOpened, 1, true); - accordion.isAccordionItemExpanded(initiallyOpened, 2, false); - accordion.isItemContentVisible(initiallyOpened, 0, false); - accordion.isItemContentVisible(initiallyOpened, 1, true); - accordion.isItemContentVisible(initiallyOpened, 2, false); - }); - - it('when user click on 2d item, it should be closed', () => { - accordion.clickOnAccordionGroup(initiallyOpened, 1); - accordion.isAccordionItemExpanded(initiallyOpened, 1, false); - accordion.isItemContentVisible(initiallyOpened, 1, false); - }); - - it('when user click on 1t or 3d item, it should be opened', () => { - accordion.clickOnAccordionGroup(initiallyOpened, 0); - accordion.clickOnAccordionGroup(initiallyOpened, 2); - accordion.isAccordionItemExpanded(initiallyOpened, 0, true); - accordion.isAccordionItemExpanded(initiallyOpened, 2, true); - accordion.isItemContentVisible(initiallyOpened, 0, true); - accordion.isItemContentVisible(initiallyOpened, 2, true); - }); - - it('when user click on 2d item, it should be closed, after reload page, it become expanded', () => { - accordion.clickOnAccordionGroup(initiallyOpened, 1); - accordion.isAccordionItemExpanded(initiallyOpened, 1, false); - accordion.isItemContentVisible(initiallyOpened, 1, false); - cy.reload(); - accordion.isAccordionItemExpanded(initiallyOpened, 1, true); - accordion.isItemContentVisible(initiallyOpened, 1, true); - }); - }); - - describe('Dynamic accordion', () => { - const dynamicAccordion = accordion.exampleDemosArr.dynamicAccordion; - - beforeEach(() => accordion.scrollToMenu('Dynamic accordion')); - - it(`example contains 2 accordion items, initially not expanded and button "Add Group Item"`, () => { - accordion.isAccordionLengthEqual(dynamicAccordion, 2); - accordion.isAccordionItemExpanded(dynamicAccordion, 0, false); - accordion.isAccordionItemExpanded(dynamicAccordion, 1, false); - accordion.isItemContentVisible(dynamicAccordion, 0, false); - accordion.isItemContentVisible(dynamicAccordion, 1, false); - accordion.isBtnTxtEqual(dynamicAccordion, ' Add Group Item '); - }); - - it(`when user click on each item, it opens and content inside shown`, () => { - accordion.clickOnAccordionGroup(dynamicAccordion, 0); - accordion.clickOnAccordionGroup(dynamicAccordion, 1); - accordion.isAccordionItemExpanded(dynamicAccordion, 0, true); - accordion.isAccordionItemExpanded(dynamicAccordion, 1, true); - accordion.isItemContentVisible(dynamicAccordion, 0, true); - accordion.isItemContentVisible(dynamicAccordion, 1, true); - }); - - it(`when user click on "Add Group Item" button then new item added, - when user click on just added new item, then shown content inside`, () => { - accordion.clickOnBtn(dynamicAccordion); - accordion.isAccordionLengthEqual(dynamicAccordion, 3); - accordion.isAccordionItemExpanded(dynamicAccordion, 2, false); - accordion.isItemContentVisible(dynamicAccordion, 2, false); - accordion.clickOnAccordionGroup(dynamicAccordion, 2); - accordion.isAccordionItemExpanded(dynamicAccordion, 2, true); - accordion.isItemContentVisible(dynamicAccordion, 2, true); - }); - - it(`when user click on "Add Group Item" N times, the amount of items increased on N - when user reload page, amount of items in Accordion dynamic block should be 2`, () => { - accordion.clickOnBtn(dynamicAccordion); - accordion.clickOnBtn(dynamicAccordion); - accordion.clickOnBtn(dynamicAccordion); - accordion.clickOnBtn(dynamicAccordion); - accordion.isAccordionLengthEqual(dynamicAccordion, 6); - cy.reload(); - accordion.isAccordionLengthEqual(dynamicAccordion, 2); - }); - }); - - describe('Dynamic body content', () => { - const dynamicBody = accordion.exampleDemosArr.dynamicBody; - const itemBody = '.panel-body'; - - beforeEach(() => accordion.scrollToMenu('Dynamic body content')); - - it(`example contains 3 accordion items, initially not expanded`, () => { - accordion.isAccordionLengthEqual(dynamicBody, 3); - accordion.isAccordionItemExpanded(dynamicBody, 0, false); - accordion.isAccordionItemExpanded(dynamicBody, 1, false); - accordion.isAccordionItemExpanded(dynamicBody, 2, false); - accordion.isItemContentVisible(dynamicBody, 0, false); - accordion.isItemContentVisible(dynamicBody, 1, false); - accordion.isItemContentVisible(dynamicBody, 2, false); - }); - - it(`when user click on 1st item, then user see "Add Item" button, there is 3 div-blocks`, () => { - accordion.clickOnAccordionGroup(dynamicBody, 0); - accordion.isAccordionItemExpanded(dynamicBody, 0, true); - accordion.isItemContentVisible(dynamicBody, 0, true); - accordion.isButtonExist(dynamicBody, 'Add Item ', 1); - accordion.isAccordionItemContain(dynamicBody, '.panel-body', 0, 'Item 1Item 2Item 3', true); - }); - - it(`when user click on "Add Item" button, amount of div-blocks inside should be increased to 4, - when click on "Add Item" again, amount of div-blocks inside should be increased to 5`, () => { - accordion.clickOnAccordionGroup(dynamicBody, 0); - accordion.clickOnBtn(dynamicBody, 1); - accordion.isAccordionItemContain(dynamicBody, itemBody, 0, 'Item 1Item 2Item 3Item 4', true); - accordion.clickOnBtn(dynamicBody, 1); - accordion.isAccordionItemContain(dynamicBody, itemBody, 0, 'Item 1Item 2Item 3Item 4Item 5', true); - accordion.clickOnBtn(dynamicBody, 1); - accordion.isAccordionItemContain(dynamicBody, itemBody, 0, 'Item 1Item 2Item 3Item 4Item 5Item 6', true); - }); - - it(`when user click on "Add Item" button a few times, and then reload page, - then amount of items should back to default (3 items and 3 div-blocks inside first item)`, () => { - accordion.clickOnAccordionGroup(dynamicBody, 0); - accordion.clickOnBtn(dynamicBody, 1); - accordion.clickOnBtn(dynamicBody, 1); - accordion.isAccordionItemExpanded(dynamicBody, 0, true); - accordion.isAccordionItemContain(dynamicBody, itemBody, 0, 'Item 1Item 2Item 3Item 4Item 5', true); - cy.reload(); - accordion.isAccordionItemExpanded(dynamicBody, 0, false); - accordion.clickOnAccordionGroup(dynamicBody, 0); - accordion.isAccordionItemExpanded(dynamicBody, 0, true); - accordion.isAccordionItemContain(dynamicBody, itemBody, 0, 'Item 1Item 2Item 3', true); - }); - }); - - describe('Manual toggle', () => { - const manualToggle = accordion.exampleDemosArr.manualToggle; - - beforeEach(() => accordion.scrollToMenu('Manual toggle')); - - it(`example contains 3 accordion items, only 3d initially expanded and 1 button "Toggle last panel"`, () => { - accordion.isAccordionLengthEqual(manualToggle, 3); - accordion.isAccordionItemExpanded(manualToggle, 0, false); - accordion.isAccordionItemExpanded(manualToggle, 1, false); - accordion.isAccordionItemExpanded(manualToggle, 2, true); - accordion.isItemContentVisible(manualToggle, 0, false); - accordion.isItemContentVisible(manualToggle, 1, false); - accordion.isItemContentVisible(manualToggle, 2, true); - accordion.isBtnTxtEqual(manualToggle, 'Toggle last panel '); - }); - - it('when user click on "Toggle last panel" button, then last item closed and user see content inside', () => { - accordion.clickOnBtn(manualToggle); - accordion.isAccordionItemExpanded(manualToggle, 2, false); - accordion.isItemContentVisible(manualToggle, 2, false); - }); - - it('when user click on "Toggle last panel" button second time, then last item opened again', () => { - accordion.clickOnBtn(manualToggle); - accordion.clickOnBtn(manualToggle); - accordion.isAccordionItemExpanded(manualToggle, 2, true); - accordion.isItemContentVisible(manualToggle, 2, true); - }); - }); - - describe('Open only one at a time', () => { - const oneAtATime = accordion.exampleDemosArr.oneAtATime; - - beforeEach(() => accordion.scrollToMenu('Open only one at a time')); - - it(`example contains 3 accordion items, initially not expanded and 1 checkbox "Open only one at a time"`, () => { - accordion.isAccordionLengthEqual(oneAtATime, 3); - accordion.isAccordionItemExpanded(oneAtATime, 0, false); - accordion.isAccordionItemExpanded(oneAtATime, 1, false); - accordion.isAccordionItemExpanded(oneAtATime, 2, false); - accordion.isItemContentVisible(oneAtATime, 0, false); - accordion.isItemContentVisible(oneAtATime, 1, false); - accordion.isItemContentVisible(oneAtATime, 2, false); - accordion.isLabelTxtEqual(oneAtATime, ' Open only one at a time '); - }); - - it(`when user click on 1st item, it opened, when user click on 2d item, it opened and 1st is closed - when user click on 3d item, it opened and 2d is closed`, () => { - accordion.clickOnAccordionGroup(oneAtATime, 0); - accordion.isAccordionItemExpanded(oneAtATime, 0, true); - accordion.isAccordionItemExpanded(oneAtATime, 1, false); - accordion.isAccordionItemExpanded(oneAtATime, 2, false); - accordion.clickOnAccordionGroup(oneAtATime, 1); - accordion.isItemContentVisible(oneAtATime, 0, false); - accordion.isItemContentVisible(oneAtATime, 1, true); - accordion.isItemContentVisible(oneAtATime, 2, false); - accordion.clickOnAccordionGroup(oneAtATime, 2); - accordion.isItemContentVisible(oneAtATime, 0, false); - accordion.isItemContentVisible(oneAtATime, 1, false); - accordion.isItemContentVisible(oneAtATime, 2, true); - }); - - it(`when user uncheck the check-box, then after click on each item, it stay opened`, () => { - accordion.clickCheckbox(oneAtATime, false); - accordion.clickOnAccordionGroup(oneAtATime, 0); - accordion.clickOnAccordionGroup(oneAtATime, 1); - accordion.clickOnAccordionGroup(oneAtATime, 2); - accordion.isAccordionItemExpanded(oneAtATime, 0, true); - accordion.isAccordionItemExpanded(oneAtATime, 1, true); - accordion.isAccordionItemExpanded(oneAtATime, 2, true); - }); - }); - - describe('Styling', () => { - const styling = accordion.exampleDemosArr.styling; - - beforeEach(() => accordion.scrollToMenu('Styling')); - - it(`example contains 3 accordion items, only 1st initially expanded`, () => { - accordion.isAccordionLengthEqual(styling, 3); - accordion.isAccordionItemExpanded(styling, 0, true); - accordion.isAccordionItemExpanded(styling, 1, false); - accordion.isAccordionItemExpanded(styling, 2, false); - accordion.isItemContentVisible(styling, 0, true); - accordion.isItemContentVisible(styling, 1, false); - accordion.isItemContentVisible(styling, 2, false); - }); - - it(`styles for the 1st and 3d items and it content should be the same (from the customClass styles) - styling for the 2d item and content should be default`, () => { - const colors = [ - 'rgb(91, 192, 222)', // light blue (malibu) - 'rgb(255, 255, 255)', // white - 'rgb(51, 122, 167)', // dark blue (lochmara) - 'rgb(33, 37, 41)', // grey - 'rgba(0, 0, 0, 0)' // black - ]; - accordion.isAccordionItemHaveCorrectStyle(styling, 0, colors[0], colors[1]); - accordion.isAccordionBodyHaveCorrectStyle(styling, 0, colors[2], colors[1]); - accordion.isAccordionItemHaveCorrectStyle(styling, 2, colors[0], colors[1]); - accordion.isAccordionBodyHaveCorrectStyle(styling, 2, colors[2], colors[1]); - accordion.isAccordionItemHaveCorrectStyle(styling, 1, colors[1], colors[3]); - accordion.isAccordionBodyHaveCorrectStyle(styling, 1, colors[4], colors[3]); - }); - }); - - describe('Configuring defaults', () => { - const configDefaults = accordion.exampleDemosArr.config; - - beforeEach(() => { - cy.viewport(1440, 900); - accordion.clickOnDemoMenu('Configuring defaults'); - }); - - it(`example contains 3 accordion items, initially not expanded - src of component contains info how to override AccordionConfig`, () => { - accordion.isAccordionLengthEqual(configDefaults, 3); - accordion.isAccordionItemExpanded(configDefaults, 0, false); - accordion.isAccordionItemExpanded(configDefaults, 1, false); - accordion.isAccordionItemExpanded(configDefaults, 2, false); - accordion.isItemContentVisible(configDefaults, 0, false); - accordion.isItemContentVisible(configDefaults, 1, false); - accordion.isItemContentVisible(configDefaults, 2, false); - accordion.isComponentSrcContain('Configuring defaults', 'provide: AccordionConfig'); - accordion.isComponentSrcContain('Configuring defaults', 'closeOthers: true'); - }); - - it(`when user click on 1st item, it opened, when user click on 2d item, it opened and 1st is closed - when user click on 3d item, it opened and 2d is closed`, () => { - accordion.clickOnAccordionGroup(configDefaults, 0); - accordion.isAccordionItemExpanded(configDefaults, 0, true); - accordion.isAccordionItemExpanded(configDefaults, 1, false); - accordion.isAccordionItemExpanded(configDefaults, 2, false); - accordion.clickOnAccordionGroup(configDefaults, 1); - accordion.isItemContentVisible(configDefaults, 0, false); - accordion.isItemContentVisible(configDefaults, 1, true); - accordion.isItemContentVisible(configDefaults, 2, false); - accordion.clickOnAccordionGroup(configDefaults, 2); - accordion.isItemContentVisible(configDefaults, 0, false); - accordion.isItemContentVisible(configDefaults, 1, false); - accordion.isItemContentVisible(configDefaults, 2, true); - }); - }); -}); diff --git a/apps/ngx-bootstrap-docs-e2e/src/full/alerts_page.spec.ts b/apps/ngx-bootstrap-docs-e2e/src/full/alerts_page.spec.ts new file mode 100644 index 0000000000..41f7cd3ea1 --- /dev/null +++ b/apps/ngx-bootstrap-docs-e2e/src/full/alerts_page.spec.ts @@ -0,0 +1,254 @@ +import { test as base } from '@playwright/test'; +import { AlertsPo } from '../support/alerts.po'; + +const test = base.extend<{ alertsPo: AlertsPo }>({ + alertsPo: async ({ page }, use) => { + const alertsPo = new AlertsPo(page); + await use(alertsPo); + }, +}); + +test.describe('Alerts page testing suite', () => { + let tabName: string; + let tabSelector: string; + + test.beforeEach(async ({ alertsPo }) => { + tabName = 'Overview'; + tabSelector = `tab[heading="${tabName}"]`; + await alertsPo.navigateTo(); + }); + + test.describe('Link color', () => { + let linkColor: string; + + test.beforeEach(async ({ alertsPo }) => { + linkColor = tabSelector + alertsPo.exampleDemosArr.link; + await alertsPo.scrollToMenu('Link color'); + }); + + test(`example contains 4 alerts with types: success, info, warning, danger + each alert have clickable link with class alert-link`, async ({ alertsPo }) => { + await alertsPo.expectAlertVisible(linkColor, 'success'); + await alertsPo.expectAlertHaveLink(linkColor, 'success'); + await alertsPo.expectAlertVisible(linkColor, 'info'); + await alertsPo.expectAlertHaveLink(linkColor, 'info'); + await alertsPo.expectAlertVisible(linkColor, 'warning'); + await alertsPo.expectAlertHaveLink(linkColor, 'warning'); + await alertsPo.expectAlertVisible(linkColor, 'danger'); + await alertsPo.expectAlertHaveLink(linkColor, 'danger'); + }); + }); + + test.describe('Additional content', () => { + let additionalContent: string; + + test.beforeEach(async ({ alertsPo }) => { + additionalContent = tabSelector + alertsPo.exampleDemosArr.content; + await alertsPo.scrollToMenu('Additional content'); + }); + + test(`example contains 1 alert with type: success, content inside contains header h4 and 2 paragraphs`, async ({ alertsPo }) => { + await alertsPo.expectAlertVisible(additionalContent, 'success'); + await alertsPo.expectAlertHaveDescendants(additionalContent, 'success', 'h4'); + await alertsPo.expectAlertHaveDescendants(additionalContent, 'success', 'p'); + await alertsPo.expectAlertHaveDescendants(additionalContent, 'success', '.mb-0'); + }); + }); + + test.describe('Dismissing', () => { + let dismissing: string; + + test.beforeEach(async ({ alertsPo }) => { + dismissing = tabSelector + alertsPo.exampleDemosArr.dismissing; + await alertsPo.scrollToMenu('Dismissing'); + }); + + test(`example contains 3 alerts with types: success, info, danger, + 2 clickable buttons: "Toggle dismissible", "Reset`, async ({ alertsPo }) => { + await alertsPo.expectAlertVisible(dismissing, 'success'); + await alertsPo.expectAlertVisible(dismissing, 'info'); + await alertsPo.expectAlertVisible(dismissing, 'danger'); + await alertsPo.expectBtnTxtEqual(dismissing, 'Toggle dismissible', 3); + await alertsPo.expectBtnTxtEqual(dismissing, 'Reset', 4); + }); + + test(`when user click on close button, then alert disappeared`, async ({ alertsPo }) => { + await alertsPo.clickOnBtn(dismissing, 2); + await alertsPo.expectAlertVisible(dismissing, 'danger', false); + await alertsPo.clickOnBtn(dismissing, 1); + await alertsPo.expectAlertVisible(dismissing, 'info', false); + await alertsPo.clickOnBtn(dismissing, 0); + await alertsPo.expectAlertVisible(dismissing, 'success', false); + }); + + test(`when user click "Reset" - then alerts back to default (3 alert with close buttons)`, async ({ alertsPo }) => { + await alertsPo.clickOnBtn(dismissing, 2); + await alertsPo.clickOnBtn(dismissing, 1); + await alertsPo.clickOnBtn(dismissing, 0); + await alertsPo.clickOnBtn(dismissing, 1); + await alertsPo.expectAlertVisible(dismissing, 'success'); + await alertsPo.expectAlertVisible(dismissing, 'info'); + await alertsPo.expectAlertVisible(dismissing, 'danger'); + await alertsPo.expectBtnExist(dismissing, '×Close', 0); + await alertsPo.expectBtnExist(dismissing, '×Close', 1); + await alertsPo.expectBtnExist(dismissing, '×Close', 2); + }); + + test(`when user click "Toggle dismissible", then close buttons disappeared`, async ({ alertsPo }) => { + await alertsPo.clickOnBtn(dismissing, 3); + await alertsPo.expectAlertVisible(dismissing, 'success'); + await alertsPo.expectAlertVisible(dismissing, 'info'); + await alertsPo.expectAlertVisible(dismissing, 'danger'); + await alertsPo.expectBtnNotExist(dismissing, '×Close'); + await alertsPo.expectBtnNotExist(dismissing, '×Close'); + await alertsPo.expectBtnNotExist(dismissing, '×Close'); + }); + + test(`when user click "Toggle dismissible" again, then close buttons appeared`, async ({ alertsPo }) => { + await alertsPo.dblClickOnBtn(dismissing, 3); + await alertsPo.expectAlertVisible(dismissing, 'success'); + await alertsPo.expectAlertVisible(dismissing, 'info'); + await alertsPo.expectAlertVisible(dismissing, 'danger'); + await alertsPo.expectBtnExist(dismissing, '×Close', 0); + await alertsPo.expectBtnExist(dismissing, '×Close', 1); + await alertsPo.expectBtnExist(dismissing, '×Close', 2); + }); + }); + + test.describe('Dynamic html', () => { + let dynamicHtml: string; + + test.beforeEach(async ({ alertsPo }) => { + dynamicHtml = tabSelector + alertsPo.exampleDemosArr.dynamicHtml; + await alertsPo.scrollToMenu('Dynamic html'); + }); + + test(`example contains 3 alerts with types: success, info, danger, + src of component code should contain DomSanitizer for sanitizing html`, async ({ alertsPo }) => { + await alertsPo.expectAlertVisible(dynamicHtml, 'success'); + await alertsPo.expectAlertVisible(dynamicHtml, 'info'); + await alertsPo.expectAlertVisible(dynamicHtml, 'danger'); + await alertsPo.expectAlertHaveDescendants(dynamicHtml, 'success', 'span'); + await alertsPo.expectAlertHaveDescendants(dynamicHtml, 'info', 'span'); + await alertsPo.expectAlertHaveDescendants(dynamicHtml, 'danger', 'span'); + await alertsPo.expectComponentSrcContain('Dynamic html', 'DomSanitizer'); + }); + }); + + test.describe('Dynamic content', () => { + let dynamicContent: string; + + test.beforeEach(async ({ alertsPo }) => { + dynamicContent = tabSelector + alertsPo.exampleDemosArr.dynamicContent; + await alertsPo.scrollToMenu('Dynamic html'); + }); + + test(`example contains 1 alert with type: success and "Change text" button`, async ({ alertsPo }) => { + await alertsPo.expectAlertVisible(dynamicContent, 'success'); + await alertsPo.expectBtnTxtEqual(dynamicContent, 'Change text'); + }); + + test(`when user click on this button, alert content changed, after click on it 2d, content changed again, + when click on it 3d, then button changed to "Reset" and after click on it - content form 1t`, async ({ alertsPo }) => { + await alertsPo.expectAlertTextContains(dynamicContent, 'success', 'You successfully read this important alert'); + await alertsPo.clickOnBtn(dynamicContent); + await alertsPo.expectAlertVisible(dynamicContent, 'success'); + await alertsPo.expectAlertTextContains(dynamicContent, 'success', 'Now this text is different from what it was before'); + await alertsPo.clickOnBtn(dynamicContent); + await alertsPo.expectAlertVisible(dynamicContent, 'success'); + await alertsPo.expectAlertTextContains(dynamicContent, 'success', 'Well done! Click reset button'); + await alertsPo.expectBtnTxtEqual(dynamicContent, 'Reset'); + await alertsPo.clickOnBtn(dynamicContent); + await alertsPo.expectAlertTextContains(dynamicContent, 'success', 'You successfully read this important alert'); + }); + }); + + test.describe('Dismiss on timeout', () => { + + // There are added some timeouts in tests below, that we need to wait until alerts disappear + // TODO remove these timeouts to speed up the tests run after this feature will be implemented + // https://github.com/microsoft/playwright/issues/6347 + + const timeout = 10000; + let dismissTimeout: string; + + test.beforeEach(async ({ alertsPo }) => { + dismissTimeout = tabSelector + alertsPo.exampleDemosArr.dismissTimeout; + test.setTimeout(timeout); + }); + + test('example contains 1 success alert and "Add more" button', async ({ alertsPo }) => { + await alertsPo.expectAlertVisible(dismissTimeout, 'success'); + await alertsPo.expectBtnTxtEqual(dismissTimeout, 'Add more'); + await alertsPo.expectAlertVisible(dismissTimeout, 'success', false, timeout); + }); + + test('when user click on "Add more" button, then info alert shown', async ({ alertsPo }) => { + await alertsPo.expectAlertVisible(dismissTimeout, 'success', false, timeout); + await alertsPo.clickOnBtn(dismissTimeout); + await alertsPo.expectAlertVisible(dismissTimeout, 'info'); + }); + + test('when user in a short time (up to 5 sec) click on button a few times, then a few alerts shown', async ({ alertsPo }) => { + await alertsPo.clickOnBtn(dismissTimeout); + await alertsPo.clickOnBtn(dismissTimeout); + await alertsPo.clickOnBtn(dismissTimeout); + await alertsPo.expectAlertCountEqual(dismissTimeout, 4); + await alertsPo.expectAlertCountEqual(dismissTimeout, 0, timeout); + }); + }); + + test.describe('Global styling', () => { + let globalStyling: string; + + test.beforeEach(async ({ alertsPo }) => { + globalStyling = tabSelector + alertsPo.exampleDemosArr.globalStyling; + await alertsPo.scrollToMenu('Global styling'); + }); + + test(`example contains 1 alert with specific style, differs from default, template src contains this style`, async ({ alertsPo }) => { + await alertsPo.expectAlertVisible(globalStyling, 'colored'); + await alertsPo.expectAlertHaveCss(globalStyling, 'background-color', 'rgb(123, 31, 162)'); + await alertsPo.expectAlertHaveCss(globalStyling, 'border-color', 'rgb(74, 20, 140)'); + await alertsPo.expectAlertHaveCss(globalStyling, 'color', 'rgb(255, 255, 255)'); + await alertsPo.expectTemplateSrcContain('Global styling', '