diff --git a/.travis.yml b/.travis.yml index 36a068a2..c473d22b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,14 @@ sudo: required +dist: xenial language: node_js -cache: - directories: - - node_modules notifications: email: false node_js: - '10' services: - xvfb +addons: + chrome: stable before_script: - npm prune script: diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..1d9e7361 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at dlotts@knightrider.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/README.es_MX.md b/README.es_MX.md index 96b9590c..9828f913 100644 --- a/README.es_MX.md +++ b/README.es_MX.md @@ -102,6 +102,16 @@ Utiliza las clases `row` y `col` de bootstrap flex para el acomodo del component Si el contenedor padre no es lo suficientemente ancho (mayor a 340px) el diseño de la fila y columna que contiene el componente puede que no se muestre de manera atractiva. Otros lenguajes/locales es probable que requieran un contenedor un poco mas ancho para poder mostrar apropiadamente el contenido. +## End-to-End (e2e) testing with protractor + +**Translation Pull request needed for this section** + +The user interactions with a date-time picker make it difficult to write e2e tests that exactly replicate the users interaction with the picker. + +Fortunately, this repository contains a file you can use in your e2e tests to cause the date/time picker to select any specified date. + +See [./e2e/src/dl-date-time-picker-protractor.ts](./e2e/src/dl-date-time-picker-protractor.ts) for details. + ## Configuración Utiliza el [generador de configuración automatizado](https://stackblitz.com/github/dalelotts/angular-bootstrap-datetimepicker-demo) (por favor hazme saber si no funciona para tu caso!), o ve a [https://dalelotts.github.io/angular-bootstrap-datetimepicker/](https://dalelotts.github.io/angular-bootstrap-datetimepicker/) @@ -229,13 +239,5 @@ angular-bootstrap-datetimepicker fué liberada con la licencia MIT y copyright 2 La licencia completa de angular-bootstrap-datetimepicker se encuentra [en el repositorio del proyecto](LICENSE) para más información. -## Donativos -Puedes apoyar este proyecto y otros relizados por Dale Lotts por medio de [gittip][gittip-dalelotts]. - -[![Apoya via Gittip][gittip-badge]][gittip-dalelotts] - -[gittip-badge]: https://rawgithub.com/twolfson/gittip-badge/master/dist/gittip.png -[gittip-dalelotts]: https://www.gittip.com/dalelotts/ - [license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat [license-url]: LICENSE diff --git a/README.md b/README.md index 07c20b32..905a5c7b 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,14 @@ It uses bootstrap's flex `row` and `col` classes to layout the date/time picker If the parent container is too narrow (less than 340px in english), the row and column layout may wrap in ways that are not attractive. Other languages/locals may require a wider container to fit the contents. +## End-to-End (e2e) testing with protractor + +The user interactions with a date-time picker make it difficult to write e2e tests that exactly replicate the users interaction with the picker. + +Fortunately, this repository contains a file you can use in your e2e tests to cause the date/time picker to select any specified date. + +See [./e2e/src/dl-date-time-picker-protractor.ts](./e2e/src/dl-date-time-picker-protractor.ts) for details. + ## Configuration Use the [automated configuration generator](https://stackblitz.com/github/dalelotts/angular-bootstrap-datetimepicker-demo) (please let me know if it does not work for your use case!), @@ -239,13 +247,5 @@ angular-bootstrap-datetimepicker is released under the MIT license and is copyri The full angular-bootstrap-datetimepicker license is located [in the project repository](LICENSE) for more information. -## Donating -Support this project and other work by Dale Lotts via [gittip][gittip-dalelotts]. - -[![Support via Gittip][gittip-badge]][gittip-dalelotts] - -[gittip-badge]: https://rawgithub.com/twolfson/gittip-badge/master/dist/gittip.png -[gittip-dalelotts]: https://www.gittip.com/dalelotts/ - [license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat [license-url]: LICENSE diff --git a/e2e/src/app.e2e-spec.ts b/e2e/src/app.e2e-spec.ts index b0274545..22ed4683 100644 --- a/e2e/src/app.e2e-spec.ts +++ b/e2e/src/app.e2e-spec.ts @@ -1,14 +1,22 @@ -import { AppPage } from './app.po'; +import {AppPage} from './app.po'; +import pickTime from './dl-date-time-picker-protractor'; +import moment = require('moment'); describe('workspace-project App', () => { let page: AppPage; beforeEach(() => { page = new AppPage(); + return page.navigateTo(); }); - it('should display welcome message', () => { - page.navigateTo(); - expect(page.getParagraphText()).toEqual('Welcome to angular-bootstrap-datetimepicker!'); + it('Picking time updates Selected Date:', async () => { + const todayAtMidnight = moment('2003-11-07T21:32:17.800Z'); + const expectedDate = new Date('2003-11-07T21:30:00.000Z').toString(); + + await pickTime(page.getDateTimePicker(), todayAtMidnight.valueOf()); + + const selectedDate = page.getSelectedDate().getText(); + expect(selectedDate).toBe(`Selected Date: ${expectedDate}`); }); }); diff --git a/e2e/src/app.po.ts b/e2e/src/app.po.ts index 82ea75ba..56a1eaf4 100644 --- a/e2e/src/app.po.ts +++ b/e2e/src/app.po.ts @@ -8,4 +8,12 @@ export class AppPage { getParagraphText() { return element(by.css('app-root h1')).getText(); } + + getDateTimePicker() { + return element(by.tagName('dl-date-time-picker')); + } + + getSelectedDate() { + return element(by.id('selectedDate')); + } } diff --git a/e2e/src/dl-date-time-picker-protractor.ts b/e2e/src/dl-date-time-picker-protractor.ts new file mode 100644 index 00000000..02cad33f --- /dev/null +++ b/e2e/src/dl-date-time-picker-protractor.ts @@ -0,0 +1,83 @@ +import {by, ElementArrayFinder, ElementFinder} from 'protractor'; + +/** + * This file is an example of how you can implement automated end-to-end tests for the + * date/time picker component. + * + * The overall strategy here is to use the `dl-abdtp-value` attributes, which contain numeric date values, + * to determine which buttons to click on the picker in order to select a target dates. + */ + +/** + * Clicks the nearest date button with a value less than or equal to the specified time. + * @param dateButtons + * the possible date buttons. + * @param time + * the desired selected time. + */ + +export function clickNearestDateButton(dateButtons: ElementArrayFinder, time: number) { + return dateButtons + .filter(button => button.getAttribute('dl-abdtp-value').then(buttonValue => Number(buttonValue) <= time)) + .last().click(); +} + +/** + * Have the dateTimePicker select the best possible value that is less than or equal to the specified time. + * based on the current configuration of the dateTimePicker. + * + * This function will `not` select a time value `greater than` the specified time value. + * + * Additionally, this function depends on `ng-reflect-*` attributes which will never exist in a production build. + * + * @param dateTimePicker + * the target dateTimePicker + * + * @param time + * the desired selected time. + */ +async function pickTime(dateTimePicker: ElementFinder, time: number) { + const dateButtons = dateTimePicker.all(by.className('dl-abdtp-date-button')); + const leftButton = dateTimePicker.element(by.className('dl-abdtp-left-button')); + const rightButton = dateTimePicker.element(by.className('dl-abdtp-right-button')); + const upButton = dateTimePicker.element(by.className('dl-abdtp-up-button')); + const viewAttributeName = 'data-dl-abdtp-view'; + const viewElement = dateTimePicker.element(by.css(`[${viewAttributeName}]`)); + + const maxView = await dateTimePicker.getAttribute('ng-reflect-max-view'); + const minView = await dateTimePicker.getAttribute('ng-reflect-min-view'); + + let currentView = await viewElement.getAttribute(viewAttributeName); + + // Go up to the max view in order to drill down by selecting the nearest button value. + while (maxView !== currentView) { + await upButton.click(); + currentView = await viewElement.getAttribute(viewAttributeName); + } + + let firstButtonValue = await dateButtons.first().getAttribute('dl-abdtp-value'); + + // This left and right navigation to find the target date range assumes that earlier times are to the left. + // This is true for the default implementation but may not be true for all implementations. + + while (Number(firstButtonValue) > time) { + await leftButton.click(); + firstButtonValue = await dateButtons.first().getAttribute('dl-abdtp-value'); + } + + let lastButtonValue = await dateButtons.last().getAttribute('dl-abdtp-value'); + + while (Number(lastButtonValue) <= time) { + await rightButton.click(); + lastButtonValue = await dateButtons.last().getAttribute('dl-abdtp-value'); + } + + while (minView !== currentView) { + await clickNearestDateButton(dateButtons, time); + currentView = await viewElement.getAttribute(viewAttributeName); + } + + return clickNearestDateButton(dateButtons, time); +} + +export default pickTime; diff --git a/images/coverage-badge.svg b/images/coverage-badge.svg index e297156d..d12452ae 100644 --- a/images/coverage-badge.svg +++ b/images/coverage-badge.svg @@ -1,9 +1 @@ - + \ No newline at end of file diff --git a/package.json b/package.json index f3f1eef9..dc9fc1ad 100644 --- a/package.json +++ b/package.json @@ -31,12 +31,12 @@ "build:styles": "scss-bundle -c scss-bundle.config.json", "coverage:upload": "cat build/coverage/lcov.info | coveralls", "document": "compodoc --disableInternal --disablePrivate --disableLifeCycleHooks --assetsFolder screenshots -p src/tsconfig.doc.json --gaID UA-325325-19 -n \"Angular Bootstrap Date/Time Picker\"", - "e2e": "ng e2e", "lint": "ng lint", "ng": "ng", "start": "ng serve", - "test": "ng lint && ng test --watch=false --code-coverage && ng build --prod && npm run build:lib", + "test": "ng lint && ng test --watch=false --code-coverage && npm run-script test:e2e && ng build --prod && npm run build:lib", "test:tdd": "ng test", + "test:e2e": "ng e2e", "semantic-release": "semantic-release", "travis-deploy-once": "travis-deploy-once" }, diff --git a/screenshots/day.png b/screenshots/day.png index 21eb5484..3d0b68d8 100644 Binary files a/screenshots/day.png and b/screenshots/day.png differ diff --git a/screenshots/hour.png b/screenshots/hour.png index b5a1ed97..42b2a752 100644 Binary files a/screenshots/hour.png and b/screenshots/hour.png differ diff --git a/screenshots/minute.png b/screenshots/minute.png index 62088011..bbf888bc 100644 Binary files a/screenshots/minute.png and b/screenshots/minute.png differ diff --git a/screenshots/month.png b/screenshots/month.png index e7debc20..afef347c 100644 Binary files a/screenshots/month.png and b/screenshots/month.png differ diff --git a/screenshots/year.png b/screenshots/year.png index 09b09873..867af12f 100644 Binary files a/screenshots/year.png and b/screenshots/year.png differ diff --git a/src/app/app.component.html b/src/app/app.component.html index bfce1ed0..f038d020 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -79,6 +79,6 @@ [(ngModel)]="selectedDate" (change)="onCustomDateChange($event)"> -
Selected Date: {{selectedDate}}
+Selected Date: {{selectedDate}}
diff --git a/src/lib/dl-date-time-picker/dl-date-time-picker.component.html b/src/lib/dl-date-time-picker/dl-date-time-picker.component.html index ef87c433..0cc3a343 100644 --- a/src/lib/dl-date-time-picker/dl-date-time-picker.component.html +++ b/src/lib/dl-date-time-picker/dl-date-time-picker.component.html @@ -1,12 +1,12 @@ -