Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/FrancescoBorzi/ngx-page-object-model
https://github.com/FrancescoBorzi/ngx-page-object-model
Last synced: 15 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/FrancescoBorzi/ngx-page-object-model
- Owner: FrancescoBorzi
- License: mit
- Created: 2024-12-18T19:43:18.000Z (24 days ago)
- Default Branch: main
- Last Pushed: 2024-12-25T23:17:49.000Z (17 days ago)
- Last Synced: 2024-12-25T23:17:59.401Z (17 days ago)
- Language: TypeScript
- Size: 9.22 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-angular - ngx-page-object-model - This library streamlines the process of writing unit tests for Angular UI Components by utilizing the Page Object Model (POM) design pattern. By adopting the POM design pattern, you can create an additional layer of abstraction, effectively separating your test logic from the DOM manipulation logic. (Table of contents / Angular)
README
# ngx-page-object-model
[![CodeFactor](https://www.codefactor.io/repository/github/FrancescoBorzi/ngx-page-object-model/badge)](https://www.codefactor.io/repository/github/FrancescoBorzi/ngx-page-object-model)
[![Actions Status](https://github.com/FrancescoBorzi/ngx-page-object-model/workflows/CI/badge.svg)](https://github.com/FrancescoBorzi/ngx-page-object-model/actions)
![NPM Downloads](https://img.shields.io/npm/dw/ngx-page-object-model)ngx-page-object-model is a lightweight library designed to simplify writing [unit tests for Angular UI Components](https://javascript.plainenglish.io/component-dom-testing-in-angular-0d2256414c06) by leveraging the [Page Object Model (POM) design pattern](https://martinfowler.com/bliki/PageObject.html).
By using the Page Object Model design pattern, you can create a new abstraction level and keep your test logic separated from the logic to read and manipulate the DOM.
This library is fully Angular-based and completely testing-framework-agnostic, making it compatible with [Jasmine](https://jasmine.github.io/), [Jest](https://jestjs.io/), [Vitest](https://vitest.dev/), or any other unit testing framework.
It can be used alongside tools like [Spectator](https://ngneat.github.io/spectator/) or as a standalone solution.## Documentation and setup instructions
- https://francescoborzi.github.io/ngx-page-object-model
## Basic examples
### Example of tests without Page Object Model
In this minimalistic example, direct interaction with the DOM happens within the test itself, leading to repetition and more complex code:
```typescript
beforeEach(async () => {
// ...
fixture = TestBed.createComponent(CounterComponent);
});it('should increase the counter when clicking on the increase button', () => {
fixture.debugElement.query(By.css(`#increase-btn`)).nativeElement.click();expect(fixture.debugElement.query(By.css(`[data-testid="count"]`)).nativeElement.innerHTML).toEqual('1');
});it('should decrease the counter if the current value is greater than 0 when clicking on the decrease button', () => {
fixture.debugElement.query(By.css(`#increase-btn`)).nativeElement.click();
fixture.debugElement.query(By.css(`#increase-btn`)).nativeElement.click();fixture.debugElement.query(By.css(`#decrease-btn`)).nativeElement.click();
expect(fixture.debugElement.query(By.css(`[data-testid="count"]`)).nativeElement.innerHTML).toEqual('1');
});
```### Example of tests using the Page Object Model
With the Page Object Model pattern, the logic to interact with the DOM is encapsulated within a dedicated page object.
This approach makes tests more readable, ensures accurate typing for HTML elements, and reduces code duplication. The page object is simply a class extending `PageObjectModel`:```typescript
import { DebugHtmlElement, PageObjectModel } from 'ngx-page-object-model';class CounterPage extends PageObjectModel {
getIncreaseButton(): DebugHtmlElement {
return this.getDebugElementByCss('#increase-btn');
}
getDecreaseButton(): DebugHtmlElement {
return this.getDebugElementByCss('#decrease-btn');
}
getCount(): DebugHtmlElement {
return this.getDebugElementByTestId('count');
}clickIncreaseButton(): void {
this.getIncreaseButton().nativeElement.click();
}
clickDecreaseButton(): void {
this.getDecreaseButton().nativeElement.click();
}
}
```The test code is now cleaner, more focused, and avoids repetitive DOM manipulation:
```typescript
beforeEach(async () => {
// ...
fixture = TestBed.createComponent(CounterComponent);
page = new CounterPage(fixture);
});it('should increase the counter when clicking on the increase button', () => {
page.clickIncreaseButton();expect(page.getCount().nativeElement.innerHTML).toEqual('1');
});it('should decrease the counter if the current value is greater than 0 when clicking on the decrease button', () => {
page.clickIncreaseButton();
page.clickIncreaseButton();page.clickDecreaseButton();
expect(page.getCount().nativeElement.innerHTML).toEqual('0');
});
```## More developer-friendly errors
When using Angular default methods, running into a typo in a selector usually gives you an error like this:
> TypeError: Cannot read properties of null (reading 'nativeElement')
The methods provided by `ngx-page-object-model`, such as `getDebugElementByCss()` and `getDebugElementByTestId()`, are instead designed to produce clearer and more descriptive error messages:
> Element with selector "#some-selector" was not found.
This makes debugging a lot smoother, helping you quickly spot and fix broken CSS selectors or incorrect `data-testid` values.
### Expect an element to not be there
If you want to explicitly check that an element is not present in the DOM, you can pass `false` to disable the default assertion error:
```typescript
// Assert that the count element is not present in the DOM
expect(page.getCount(false)).not.toBeDefined();
```