diff --git a/.travis.yml b/.travis.yml index f29a7ff8b5..27740b49d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,19 @@ env: - LOGS_DIR=/tmp/logs - CY_KEY=4aa7a1c0-3a4f-444e-b324-6fc305a543a8 +# test cypress smoke +testSmokeCy: &testSmokeCy + script: + - ng serve --prod & + - $(npm bin)/wait-on http-get://localhost:4200/# + - npm run cy:run:smoke -- --record --key $CY_KEY --parallel --group $CI_THREAD_INDEX + # after all tests finish running we need + # to kill all background jobs (like "npm start &") + - kill $(jobs -p) || true + +testPostDeploy: &testPostDeploy + script: CYPRESS_baseUrl=$BASE_URL npm run cy:run:all -- --record --key $CY_KEY --parallel --group $CI_THREAD_INDEX --ci-build-id PostDeploy-$CI_THREAD_INDEX-$TRAVIS_BUILD_ID + stages: - name: Testing if: ( branch = development AND type = push ) OR type = pull_request OR tag =~ ^v\d+ @@ -26,7 +39,7 @@ stages: - name: publish if: tag =~ ^v\d+ - name: "post deploy testing" - if: branch = development AND type = push OR tag =~ ^v\d+ + if: branch = development AND type = push OR tag =~ ^v\d+ before_install: - sh -e /etc/init.d/xvfb start @@ -64,7 +77,6 @@ jobs: script: npm run lint-src name: "Lint" install: true - # test - script: npm run test-coverage name: "Test with current Angular version" @@ -73,17 +85,18 @@ jobs: name: "Test with latest Angular version" env: NGV=latest # env: NGV=next - -# test cypress smoke - script: - - ng serve --prod & - - $(npm bin)/wait-on http-get://$URL - - npm run cy:run:smoke - # after all tests finish running we need - # to kill all background jobs (like "npm start &") - - kill $(jobs -p) || true - name: "Run cypress smoke testing" - env: URL=localhost:4200/# + name: "Cypress Smoke Tests 1t thread" + env: CI_THREAD_INDEX=3x-electron + <<: *testSmokeCy + - script: + name: "Cypress Smoke Tests 2d thread" + env: CI_THREAD_INDEX=3x-electron + <<: *testSmokeCy + - script: + name: "Cypress Smoke Tests 3d thread" + env: CI_THREAD_INDEX=3x-electron + <<: *testSmokeCy # check prod build - script: npm run demo.ng-build name: "Check prod build with current Angular version" @@ -155,24 +168,59 @@ jobs: # test cypress full for herokuapp - stage: "post deploy testing" - name: "Run cypress to check SSR" +# name: "Run cypress to check SSR" # env: URL=https://ngx-universal.herokuapp.com/# - - script: ./node_modules/.bin/cypress run --config integrationFolder=cypress/integration,baseUrl=https://ngx-universal.herokuapp.com/#/ --record --key $CY_KEY - name: "Cypress integration suit run on SSR " - - script: ./node_modules/.bin/cypress run --config integrationFolder=cypress/full,baseUrl=https://ngx-universal.herokuapp.com/#/ --record --key $CY_KEY - name: "Cypress full suit run on SSR " + script: + name: "Cypress suit run on SSR 1thread" + env: + - CI_THREAD_INDEX=3x-electron + - BASE_URL=https://ngx-universal.herokuapp.com/#/ + <<: *testPostDeploy + - script: + name: "Cypress suit run on SSR 2thread" + env: + - CI_THREAD_INDEX=3x-electron + - BASE_URL=https://ngx-universal.herokuapp.com/#/ + <<: *testPostDeploy + - script: + name: "Cypress suit run on SSR 3thread" + env: + - CI_THREAD_INDEX=3x-electron + - BASE_URL=https://ngx-universal.herokuapp.com/#/ + <<: *testPostDeploy # test cypress full for gh-pages - - script: ./node_modules/.bin/cypress run --config integrationFolder=cypress/integration,baseUrl=http://ngx-bootstrap-latest.surge.sh/#/ --record --key $CY_KEY - name: "Cypres integration run with @latest angular" - - script: ./node_modules/.bin/cypress run --config integrationFolder=cypress/full,baseUrl=http://ngx-bootstrap-latest.surge.sh/#/ --record --key $CY_KEY - name: "Cypres full run with @latest angular" -# env: URL=https://valor-software.com/ngx-bootstrap/#/ - - script: ./node_modules/.bin/cypress run --config integrationFolder=cypress/integration,baseUrl=https://valor-software.com/ngx-bootstrap/#/ --record --key $CY_KEY - name: "Cypress integration on gh-pages after deploy" + - script: + name: "Cypress with @latest angular 1thread" + env: + - CI_THREAD_INDEX=3.1x-electron + - BASE_URL=http://ngx-bootstrap-latest.surge.sh/#/ + <<: *testPostDeploy + - script: + name: "Cypress with @latest angular 2thread" + env: + - CI_THREAD_INDEX=3.1x-electron + - BASE_URL=http://ngx-bootstrap-latest.surge.sh/#/ + <<: *testPostDeploy + - script: + name: "Cypress with @latest angular 3thread" + env: + - CI_THREAD_INDEX=3.1x-electron + - BASE_URL=http://ngx-bootstrap-latest.surge.sh/#/ + <<: *testPostDeploy + - script: + name: "Cypress on gh-pages after deploy 1thread" if: tag =~ ^v\d+ - - script: ./node_modules/.bin/cypress run --config integrationFolder=cypress/full,baseUrl=https://valor-software.com/ngx-bootstrap/#/ --record --key $CY_KEY - name: "Cypress full on gh-pages after deploy" + env: + - CI_THREAD_INDEX=3.2x-electron + - BASE_URL=https://valor-software.com/ngx-bootstrap/#/ + <<: *testPostDeploy + - script: + name: "Cypress on gh-pages after deploy 2thread" if: tag =~ ^v\d+ + env: + - CI_THREAD_INDEX=3.2x-electron + - BASE_URL=https://valor-software.com/ngx-bootstrap/#/ + <<: *testPostDeploy cache: apt: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 3038dcae94..785ece01b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,49 @@ + +# [3.3.0](https://github.com/valor-software/ngx-bootstrap/compare/v3.2.0...v3.3.0) (2019-02-12) + + +### Bug Fixes + +* **build:** use os specific path separator in npm run build.watch ([#4958](https://github.com/valor-software/ngx-bootstrap/issues/4958)) ([5e4183e](https://github.com/valor-software/ngx-bootstrap/commit/5e4183e)) +* **package:** decrease ts version in latest ng ([#5044](https://github.com/valor-software/ngx-bootstrap/issues/5044)) ([0e77f25](https://github.com/valor-software/ngx-bootstrap/commit/0e77f25)) +* **positioning:** fix on heroku also typeahead ([#5054](https://github.com/valor-software/ngx-bootstrap/issues/5054)) ([8d8836d](https://github.com/valor-software/ngx-bootstrap/commit/8d8836d)) +* **tabs:** adding tab content to DOM just if selected tab ([#1422](https://github.com/valor-software/ngx-bootstrap/issues/1422)) ([#4991](https://github.com/valor-software/ngx-bootstrap/issues/4991)) ([457c32a](https://github.com/valor-software/ngx-bootstrap/commit/457c32a)) +* **tests:** datepicker min-max demo - fix for weeks ([#5052](https://github.com/valor-software/ngx-bootstrap/issues/5052)) ([a2aaa80](https://github.com/valor-software/ngx-bootstrap/commit/a2aaa80)) +* **tests:** js heap out of memory, datepicker fixes ([#5048](https://github.com/valor-software/ngx-bootstrap/issues/5048)) ([235050e](https://github.com/valor-software/ngx-bootstrap/commit/235050e)) +* **tests:** rework tests accotding to new position service ([#5055](https://github.com/valor-software/ngx-bootstrap/issues/5055)) ([8a94917](https://github.com/valor-software/ngx-bootstrap/commit/8a94917)) + + +### Features + +* **datepicker:** Allow to disable specific dates ([#5046](https://github.com/valor-software/ngx-bootstrap/issues/5046)) ([5633d2d](https://github.com/valor-software/ngx-bootstrap/commit/5633d2d)) +* **positioning:** refactor positioning service ([#5027](https://github.com/valor-software/ngx-bootstrap/issues/5027)) ([66ae92d](https://github.com/valor-software/ngx-bootstrap/commit/66ae92d)), closes [#3303](https://github.com/valor-software/ngx-bootstrap/issues/3303) [#2993](https://github.com/valor-software/ngx-bootstrap/issues/2993) [#4470](https://github.com/valor-software/ngx-bootstrap/issues/4470) +* **tests:** add full e2e coverage for DatePicker component ([#4951](https://github.com/valor-software/ngx-bootstrap/issues/4951)) ([fe2b29f](https://github.com/valor-software/ngx-bootstrap/commit/fe2b29f)) +* **tests:** added cypress tests parallelization ([#5003](https://github.com/valor-software/ngx-bootstrap/issues/5003)) ([e3396bb](https://github.com/valor-software/ngx-bootstrap/commit/e3396bb)) +* **typeahead:** add Input Property for selected First item in option list ([#4631](https://github.com/valor-software/ngx-bootstrap/issues/4631)) ([cd13a55](https://github.com/valor-software/ngx-bootstrap/commit/cd13a55)), closes [#3965](https://github.com/valor-software/ngx-bootstrap/issues/3965) + + + + +# [3.2.0](https://github.com/valor-software/ngx-bootstrap/compare/v3.1.4...v3.2.0) (2019-01-21) + + +### Bug Fixes + +* **common:** prevent deprecated also fixed test (datepicker close on esc) for IE11 (souce tests) ([#4940](https://github.com/valor-software/ngx-bootstrap/issues/4940)) ([d338dbf](https://github.com/valor-software/ngx-bootstrap/commit/d338dbf)) +* **script:** fix latest script ([#5004](https://github.com/valor-software/ngx-bootstrap/issues/5004)) ([5f6a781](https://github.com/valor-software/ngx-bootstrap/commit/5f6a781)) +* **tests:** use prev safari version while latest doesnt work on sauce ([#5011](https://github.com/valor-software/ngx-bootstrap/issues/5011)) ([89f7265](https://github.com/valor-software/ngx-bootstrap/commit/89f7265)) +* **timepicker:** enable_disable timepicker in reactive forms ([#4563](https://github.com/valor-software/ngx-bootstrap/issues/4563)) ([ac55b08](https://github.com/valor-software/ngx-bootstrap/commit/ac55b08)), closes [#4055](https://github.com/valor-software/ngx-bootstrap/issues/4055) + + +### Features + +* **css:** update bootstrap css to latest ([#4999](https://github.com/valor-software/ngx-bootstrap/issues/4999)) ([91b78e7](https://github.com/valor-software/ngx-bootstrap/commit/91b78e7)) +* **datepicker:** add catalan lang ([#4969](https://github.com/valor-software/ngx-bootstrap/issues/4969)) ([20fadbd](https://github.com/valor-software/ngx-bootstrap/commit/20fadbd)), closes [#4959](https://github.com/valor-software/ngx-bootstrap/issues/4959) +* **datepicker:** Add directive for inline datepicker ([#3956](https://github.com/valor-software/ngx-bootstrap/issues/3956)) ([d9a89b4](https://github.com/valor-software/ngx-bootstrap/commit/d9a89b4)), closes [valor-software/ngx-bootstrap#3955](https://github.com/valor-software/ngx-bootstrap/issues/3955) [valor-software/ngx-bootstrap#3958](https://github.com/valor-software/ngx-bootstrap/issues/3958) +* **tooltip:** add delay to config ([#4928](https://github.com/valor-software/ngx-bootstrap/issues/4928)) ([bcf93d4](https://github.com/valor-software/ngx-bootstrap/commit/bcf93d4)), closes [#4029](https://github.com/valor-software/ngx-bootstrap/issues/4029) + + + # [3.2.0](https://github.com/valor-software/ngx-bootstrap/compare/v3.1.4...v3.2.0) (2019-01-21) diff --git a/README.md b/README.md index 2ec75282ea..cdd4f5d32c 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,9 @@ Please read central `ngx` modules [readme](https://github.com/valor-software/ng2 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/) + ### License MIT diff --git a/cypress.json b/cypress.json index 0b9d55b000..35f360b4f1 100644 --- a/cypress.json +++ b/cypress.json @@ -2,5 +2,6 @@ "baseUrl": "http://localhost:4200/#", "video": false, "projectId": "5mm2dy", - "responseTimeout": 60000 + "responseTimeout": 60000, + "ignoreTestFiles": ["**/plugins/**.js", "**/support/**", "**/tsconfig.json"] } diff --git a/cypress/full/accordion_page_spec.ts b/cypress/full/accordion_page_spec.ts new file mode 100644 index 0000000000..6c694d9c81 --- /dev/null +++ b/cypress/full/accordion_page_spec.ts @@ -0,0 +1,431 @@ +import { AccordionPo } from '../support/accordion.po'; + +describe('Accordion page test 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/cypress/full/alerts_page_spec.ts b/cypress/full/alerts_page_spec.ts new file mode 100644 index 0000000000..d6a42c400f --- /dev/null +++ b/cypress/full/alerts_page_spec.ts @@ -0,0 +1,204 @@ +import { AlertsPo } from '../support/alerts.po'; + +describe('Alerts page test suite', () => { + const alerts = new AlertsPo(); + + beforeEach(() => { + cy.clock(); + alerts.navigateTo(); + }); + + describe('Link color', () => { + const linkColor = alerts.exampleDemosArr.link; + + it(`example contains 4 alerts with types: success, info, warning, danger + each alert have clickable link with class alert-link`, () => { + alerts.scrollToMenu('Link color'); + alerts.isAlertVisible(linkColor, 'success'); + alerts.isAlertHaveLink(linkColor, 'success'); + alerts.isAlertVisible(linkColor, 'info'); + alerts.isAlertHaveLink(linkColor, 'info'); + alerts.isAlertVisible(linkColor, 'warning'); + alerts.isAlertHaveLink(linkColor, 'warning'); + alerts.isAlertVisible(linkColor, 'danger'); + alerts.isAlertHaveLink(linkColor, 'danger'); + }); + }); + + describe('Additional content', () => { + const additionalContent = alerts.exampleDemosArr.content; + + it(`example contains 1 alert with type: success, content inside contains header h4 and 2 paragraphs`, () => { + alerts.scrollToMenu('Additional content'); + alerts.isAlertVisible(additionalContent, 'success'); + alerts.isAlertContentContains(additionalContent, 'success', 'h4'); + alerts.isAlertContentContains(additionalContent, 'success', 'p'); + alerts.isAlertContentContains(additionalContent, 'success', '.mb-0'); + }); + }); + + describe('Dismissing', () => { + const dismissing = alerts.exampleDemosArr.dismissing; + + beforeEach(() => alerts.scrollToMenu('Dismissing')); + + it(`example contains 3 alerts with types: success, info, danger, + 2 clickable buttons: "Toggle dismissible", "Reset`, () => { + alerts.isAlertVisible(dismissing, 'success'); + alerts.isAlertVisible(dismissing, 'info'); + alerts.isAlertVisible(dismissing, 'danger'); + alerts.isBtnTxtEqual(dismissing, 'Toggle dismissible', 3); + alerts.isBtnTxtEqual(dismissing, 'Reset', 4); + }); + + it(`when user click on close button, then alert disappeared`, () => { + alerts.clickOnBtn(dismissing, 2); + alerts.isAlertVisible(dismissing, 'danger', false); + alerts.clickOnBtn(dismissing, 1); + alerts.isAlertVisible(dismissing, 'info', false); + alerts.clickOnBtn(dismissing, 0); + alerts.isAlertVisible(dismissing, 'success', false); + }); + + it(`when user click "Reset" - then alerts back to default (3 alert with close buttons)`, () => { + alerts.clickOnBtn(dismissing, 2); + alerts.clickOnBtn(dismissing, 1); + alerts.clickOnBtn(dismissing, 0); + alerts.clickOnBtn(dismissing, 1); + alerts.isAlertVisible(dismissing, 'success'); + alerts.isAlertVisible(dismissing, 'info'); + alerts.isAlertVisible(dismissing, 'danger'); + alerts.isButtonExist(dismissing, '×Close', 0); + alerts.isButtonExist(dismissing, '×Close', 1); + alerts.isButtonExist(dismissing, '×Close', 2); + }); + + it(`when user click "Toggle dismissible", then close buttons disappeared`, () => { + alerts.clickOnBtn(dismissing, 3); + alerts.isAlertVisible(dismissing, 'success'); + alerts.isAlertVisible(dismissing, 'info'); + alerts.isAlertVisible(dismissing, 'danger'); + alerts.isButtonExist(dismissing, '×Close', 0, false); + alerts.isButtonExist(dismissing, '×Close', 1, false); + alerts.isButtonExist(dismissing, '×Close', 2, false); + }); + + it(`when user click "Toggle dismissible" again, then close buttons appeared`, () => { + alerts.dblClickOnBtn(dismissing, 3); + alerts.isAlertVisible(dismissing, 'success'); + alerts.isAlertVisible(dismissing, 'info'); + alerts.isAlertVisible(dismissing, 'danger'); + alerts.isButtonExist(dismissing, '×Close', 0); + alerts.isButtonExist(dismissing, '×Close', 1); + alerts.isButtonExist(dismissing, '×Close', 2); + }); + }); + + describe('Dynamic html', () => { + const dynamicHtml = alerts.exampleDemosArr.dynamicHtml; + + it(`example contains 3 alerts with types: success, info, danger, + src of component code should contain DomSanitizer for sanitizing html`, () => { + alerts.scrollToMenu('Dynamic html'); + alerts.isAlertVisible(dynamicHtml, 'success'); + alerts.isAlertVisible(dynamicHtml, 'info'); + alerts.isAlertVisible(dynamicHtml, 'danger'); + alerts.isAlertContentContains(dynamicHtml, 'success', 'span'); + alerts.isAlertContentContains(dynamicHtml, 'info', 'span'); + alerts.isAlertContentContains(dynamicHtml, 'danger', 'span'); + alerts.isComponentSrcContain('Dynamic html', 'DomSanitizer'); + }); + }); + + describe('Dynamic content', () => { + const dynamicContent = alerts.exampleDemosArr.dynamicContent; + + it(`example contains 1 alert with type: success and "Change text" button`, () => { + alerts.isAlertVisible(dynamicContent, 'success'); + alerts.isBtnTxtEqual(dynamicContent, 'Change text'); + }); + + it(`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`, () => { + alerts.isAlertTextContains(dynamicContent, 'success', 'You successfully read this important alert'); + alerts.clickOnBtn(dynamicContent); + alerts.isAlertVisible(dynamicContent, 'success'); + alerts.isAlertTextContains(dynamicContent, 'success', 'Now this text is different from what it was before'); + alerts.clickOnBtn(dynamicContent); + alerts.isAlertVisible(dynamicContent, 'success'); + alerts.isAlertTextContains(dynamicContent, 'success', 'Well done! Click reset button'); + alerts.isBtnTxtEqual(dynamicContent, 'Reset'); + alerts.clickOnBtn(dynamicContent); + alerts.isAlertTextContains(dynamicContent, 'success', 'You successfully read this important alert'); + }); + }); + + describe('Dismiss on timeout', () => { + const dismissTimeout = alerts.exampleDemosArr.dismissTimeout; + + it('example contains 1 success alert and "Add more" button', () => { + alerts.isAlertVisible(dismissTimeout, 'success'); + alerts.isBtnTxtEqual(dismissTimeout, 'Add more'); + cy.tick(6000); + alerts.isAlertVisible(dismissTimeout, 'success', false); + }); + + it('when user click on "Add more" button, then info alert shown', () => { + cy.tick(6000); + alerts.isAlertVisible(dismissTimeout, 'success', false); + alerts.clickOnBtn(dismissTimeout); + alerts.isAlertVisible(dismissTimeout, 'info'); + }); + + it('when user in a short time (up to 5 sec) click on button a few times, then a few alerts shown', () => { + alerts.clickOnBtn(dismissTimeout); + alerts.clickOnBtn(dismissTimeout); + alerts.clickOnBtn(dismissTimeout); + alerts.isAlertLengthEqual(dismissTimeout, 4); + cy.tick(6000); + alerts.isAlertLengthEqual(dismissTimeout, 0); + }); + }); + + describe('Global styling', () => { + const globalStyling = alerts.exampleDemosArr.globalStyling; + + it(`example contains 1 alert with specific style, differs from default, template src contains this style`, () => { + alerts.scrollToMenu('Global styling'); + alerts.isAlertVisible(globalStyling, 'colored'); + alerts.isAlertHaveCss(globalStyling, 'background-color', 'rgb(123, 31, 162)'); + alerts.isAlertHaveCss(globalStyling, 'border-color', 'rgb(74, 20, 140)'); + alerts.isAlertHaveCss(globalStyling, 'color', 'rgb(255, 255, 255)'); + alerts.isTemplateSrcContain('Global styling', '