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/)
[
](https://saucelabs.com/)
+End-to-end testing sponsored by [Cypress](https://www.cypress.io/)
+[
](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', '