Skip to content

Commit

Permalink
Merge pull request #470 from zonemaster/develop
Browse files Browse the repository at this point in the history
Merge develop into master (GUI)
  • Loading branch information
matsduf authored Mar 18, 2024
2 parents 7b3399d + 09293dc commit 73fc1e3
Show file tree
Hide file tree
Showing 69 changed files with 6,242 additions and 2,297 deletions.
16 changes: 16 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
Release history for Zonemaster component Zonemaster-GUI


v4.2.0 2024-03-18 (public release version)

[Release information]
- Translations have not been fully updated in this release. They will
be updated in an upcoming fix release.

[Features]
- Improves GUI design (#434)

[Fixes]
- Updates FAQ (#443, #456, #457)
- Fixe handling of unspecified test module (#444)
- Updates French translation (#450)
- Updates README file (#455)


v4.1.1 2023-09-08 (public fix version)

[Fixes]
Expand Down
130 changes: 55 additions & 75 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
Zonemaster Web GUI [![Build Status](https://app.travis-ci.com/zonemaster/zonemaster-gui.svg?branch=master)](https://app.travis-ci.com/zonemaster/zonemaster-gui)
==========
# Zonemaster Web GUI [![CI status](https://github.com/zonemaster/zonemaster-gui/actions/workflows/ci.yml/badge.svg)](https://github.com/zonemaster/zonemaster-gui/actions/workflows/ci.yml)

### Purpose
This module is the Web Interface part of the Zonemaster project.

### Installation
### Purpose

Follow the detailed [installation instructions].
This module is the Web Interface part of the Zonemaster project. For an
overview of the Zonemaster software, please see the [Zonemaster repository].

##### Prerequisites
### Prerequisites

Before you install the Zonemaster Web GUI module, you need the Zonemaster
Engine test framework installed. Please see the [Zonemaster-Engine
Expand All @@ -17,103 +15,85 @@ installation] document.
You also need a running Zonemaster-Backend component. Please see the
[Zonemaster-Backend installation] document.

##### Configuration
### Installation

Follow the detailed [installation instructions].

### Configuration

The configuration instructions for the backend can be found in the [Backend
The configuration instructions for the Backend can be found in the [Backend
configuration] document.

The configuration instructions for the GUI can be found in the [GUI
configuration] document.

### Documentation

There is a [public documentation]. Some more specific documents can be found in
the [docs directory](docs/).

### Contribution

This project was generate with Angular-CLI 1.6.8 and then updating.
It use the Angular 2+ framework with all its tools.

The source code of the application is available in ``./src/app`` folder.
The ``app`` folder is structured as follow :
```
+-- components
+-- models
| +-- alter.ts : Alert model (level, message)
| +-- index.ts : module export
+-- pipes
| +-- filer.pipe.* : Filter a list based on a string
| +-- filer-by-categories.pipe.* : Filter the list of result by categories
| +-- romanize.pipe.* : Transform latin number to roman number (1 -> I, 2 -> II)
| +-- safe-html.pipe.* : Sanitize text to HTML
+-- services
| +-- alert.service.* : to display alert messages
| +-- app.service.* : to manage app configuration (api url, etc.)
| +-- dns-check.service.* : to communicate with the Zonemaster Backend API
+-- app.*
```

The ``components`` folder is composed of subfolders that represent the main components.
Each folder of component contain three files :
- ``*.component.css`` : The component's style
- ``*.component.html`` : The component's html
- ``*.component.ts`` : The component's typescript

All assets are available in ``src/assets`` folder.
It's split by concern, all translation files are in the ``i18n`` folder, the style in the ``css``,
images are in the ``images`` folder, etc.

The configurations files of the application are in the ``src/environments`` folder.
``environment.ts`` is use for development purpose, and the ``environment.prod.ts`` for production.

In order to contribute
This project was generated with Angular-CLI 1.6.8.
It uses the Angular 2+ framework with all its tools.

The source code of the application is available in `./src/app` folder.

The `components` folder is composed of subfolders that represent the main
components. Each folder of component contain three files:

* `*.component.css`: the component's style configuration;
* `*.component.html`: the component's HTML code;
* `*.component.ts`: the component's TypeScript code.

All assets are available in the `src/assets` folder. It is split by concern;
the style configurations are in the `css`, images are in the `images` folder, etc.

All translation files are in the `src/locale` folder.

The environment defaults of the application are in the `src/environments`
folder. `environment.ts` is used for development purposes, the
`environment.prod.ts` for production, and the `environment.test.ts` for testing.

In order to contribute:

* Install [Nodejs](https://nodejs.org)
* Fork the Zonemaster GUI repository on Github into your own user on Github.
* Clone your fork to your working environment.
* Go to the folder and install project dependencies with `npm install`
* Update environment files in `/src/environments/` to add a backend api endpoint (or leave the default)
* Update configuration files in `src/assets/app.config.json` to add a Backend
API endpoint (or leave the default)
* Make your changes, test them and push them to your fork on Github
* From your fork, make a Pull Request against the zonemaster/zonemaster-gui repository.
Please always make the Pull Request against the develop branch.

* From your fork, make a Pull Request against the zonemaster/zonemaster-gui
repository. Please always make the Pull Request against the develop branch.
* Thank you for your contribution!

> In development mode, you probably have to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) on your browser.
> The Cross-Origin Resource Sharing (CORS) performed by the browser blocks every AJAX request that does not match the exact host, protocol, and port of your site.
##### Development server
Run `npm start` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.

##### Build
Run `npm run build` to build the project. The build artifacts will be stored in the `dist/` directory.
The script also change the FAQ markdown files to html files.

##### Test
See [Testing](docs/Testing.md).
#### Development server

##### Create a release zip file
Run 'npm run release' to create a zip file with dist folder and zonemaster.conf file. Then upload it in github.
Run `npm start` for a dev server. Navigate to `http://localhost:4200/en`.
The app will automatically reload if you change any of the source files.

### Documentation
#### Build

There is a [public documentation]. Some more specific documents can be found in
the [docs directory](docs/).
Run `npm run build` to build the project. The build artifacts will be stored in the `dist/` directory.

#### Security of our dependencies
Based on the output of [david](https://david-dm.org/) and [npm audit](https://docs.npmjs.com/cli/audit), we reguraly
update our dependencies with the latest secure version. Notice that we can't follow the rythm of new versions, so you could
get security warning during the installation of development dependencies.
#### Test

#### Acknowledge
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.6.8.
See [Testing](docs/Testing.md).

License
=======
## License

This is free software under a 2-clause BSD license. The full text of the license can
be found in the [LICENSE](LICENSE) file included in this respository.

Images `src/assets/images/person_looking_at_computer.svg` and `src/assets/images/world_connected.svg`
are taken from <https://undraw.co>, [full license](https://undraw.co/license).


[Backend Configuration]: https://github.com/zonemaster/zonemaster/blob/master/docs/public/configuration/backend.md
[GUI Configuration]: https://github.com/zonemaster/zonemaster/blob/master/docs/public/configuration/gui.md
[Installation instructions]: https://github.com/zonemaster/zonemaster/blob/master/docs/public/installation/zonemaster-gui.md
[Public documentation]: https://github.com/zonemaster/zonemaster/blob/master/README.md#documentation
[Public documentation]: https://github.com/zonemaster/zonemaster/blob/master/docs/public/README.md
[Zonemaster-Engine installation]: https://github.com/zonemaster/zonemaster/blob/master/docs/public/installation/zonemaster-engine.md
[Zonemaster-Backend installation]: https://github.com/zonemaster/zonemaster/blob/master/docs/public/installation/zonemaster-backend.md
[Zonemaster repository]: https://github.com/zonemaster/zonemaster
6 changes: 3 additions & 3 deletions e2e/FR03.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ test.describe('Zonemaster test FR03 - [All appropriate fields should be writable
test('should be able to write in the main input', async ({ page }) => {
const testString = 'afnic.fr';

const domainInput = page.locator('#input_domain_form');
const domainInput = page.locator('#input-domain-form');
await domainInput.type(testString);
await expect(domainInput).toHaveValue(testString);

await showOptions(page);

const nsInput = page.locator('input[formControlName="ns"]');
const nsInput = page.locator('input[formControlName="ns"]').first();
await nsInput.type(testString);
await expect(nsInput).toHaveValue(testString);

const keytagInput = page.locator('input[formControlName="keytag"]');
const keytagInput = page.locator('input[formControlName="keytag"]').first();
await keytagInput.type(testString);
await expect(keytagInput).toHaveValue(testString);
});
Expand Down
7 changes: 2 additions & 5 deletions e2e/FR05.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,12 @@ test.describe('Zonemaster test FR05 - [Supports internationalization]', () => {
test(`should have ${language} language option`, async ({ page }) => {
const langNavLink = page.locator(`select#languageSelection > option[lang="${code}"]`);
await expect(langNavLink).toHaveCount(1);
await expect(langNavLink).toHaveAttribute('lang', code);
})

test(`should switch to ${language}`, async ({ page }) => {
await setLang(page, code);
await expect(page.locator('input#input_domain_form')).toHaveAttribute('placeholder', expected);

const langNavLink = page.locator(`select#languageSelection > option[lang="${code}"]`);
await expect(langNavLink).toHaveCount(1);
await expect(langNavLink).toHaveAttribute('lang', code);
await expect(page.locator('label[for="input-domain-form"]')).toHaveText(expected);
})
}
});
2 changes: 1 addition & 1 deletion e2e/FR08.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ test.describe('Zonemaster test FR08 - [Presence of a default fallback language -
});

test('should have a fallback language - English', async ({ page }) => {
await expect(page.locator('input#input_domain_form')).toHaveAttribute('placeholder', 'Domain name');
await expect(page.locator('label[for="input-domain-form"]')).toHaveText('Domain name');
});
});
4 changes: 2 additions & 2 deletions e2e/FR09.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ test.describe('Zonemaster test FR09 - [Once a language is chosen, all other link
});

test('should keep french when opening faq page', async ({ page }) => {
await expect(page.locator('input#input_domain_form')).toHaveAttribute('placeholder', 'Nom de domaine');
await expect(page.locator('label[for="input-domain-form"]')).toHaveText('Nom de domaine');
await page.locator('a.nav-link[routerlink="/faq"]').click();
await expect(page.locator('section.main > div > h1')).toHaveText('FAQ');
await expect(page.locator('main h1')).toHaveText('Questions fréquentes');
await expect(page.locator('a.nav-link[routerlink="/run-test"]')).toHaveText("Lancer un test");
});
});
10 changes: 5 additions & 5 deletions e2e/FR10.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { test, expect } = require('@playwright/test');

import { goToHome, clearBrowserCache } from './utils/app.utils';
import { goToHome, clearBrowserCache, showOptions } from './utils/app.utils';

test.describe('Zonemaster test FR10 - [On launching the URL opens with a default simple view]', () => {
test.beforeEach(async ({ page }) => {
Expand All @@ -9,21 +9,21 @@ test.describe('Zonemaster test FR10 - [On launching the URL opens with a default
});

test('should have [Run domain test] label visible', async ({ page }) => {
await expect(page.locator('h1', { hasText: 'Run domain test'})).toBeVisible();
await expect(page.locator('h1', { hasText: 'Check how your domain is doing'})).toBeVisible();
});

test('should have [Options] label visible and NOT selected', async ({ page }) => {
await expect(page.locator('label', { hasText: 'Options' })).toBeVisible();
await expect(page.locator('#advanced-toggle', { hasText: 'Show options' })).toBeVisible();

await expect(page.locator('#advanced-toggle')).toHaveAttribute('aria-expanded', 'false');
});


test('should have [Nameservers label] NOT visible', async ({ page }) => {
await expect(page.locator('h4', { hasText: 'Nameservers'})).toBeHidden();
await expect(page.locator('legend', { hasText: 'Nameservers'})).toBeHidden();
});

test('should have [DS records label] NOT visible', async ({ page }) => {
await expect(page.locator('h4', { hasText: 'Delegation Signers (DS records)'})).toBeHidden();
await expect(page.locator('legend', { hasText: 'DS records'})).toBeHidden();
});
});
Binary file modified e2e/FR11.e2e-spec.ts-snapshots/domain-chromium-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion e2e/FR15.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ test.describe('Zonemaster test FR15 - [The advanced view should look the same in

test('should match the domain page with options on', async ({ page}) => {
await showOptions(page);
// Force wait 0.4s, for the switch animation to finish
// Force wait 0.4s, for the button icon animation to finish
await page.waitForTimeout(400);
expect(await page.screenshot()).toMatchSnapshot('domain_with_options.png');
});
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions e2e/FR16.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ test.describe('Zonemaster test FR16 - [The advanced view should have a text desc
});

test('should have a link to the proper faq answer', async ({ page }) => {
const alert = page.locator('.alert.alert-info');
const alert = page.locator('#advanced-options aside .alert');
await expect(alert).toBeVisible();
await expect(alert.locator('a')).toHaveAttribute('routerlink', '/faq');
await expect(alert.locator('a')).toHaveAttribute('fragment', 'q12');
await expect(alert.locator('a')).toHaveAttribute('fragment', 'what-is-an-undelegated-domain-test');
});

test('should have a description text in multi languages', async ({ page }) => {
Expand All @@ -26,7 +26,7 @@ test.describe('Zonemaster test FR16 - [The advanced view should have a text desc
for (const {lang, text} of testSuite) {
await setLang(page, lang);
await showOptions(page);
await expect(page.locator('.alert.alert-info a')).toContainText(text);
await expect(page.locator('#advanced-options aside .alert a')).toContainText(text);
}
});
});
8 changes: 4 additions & 4 deletions e2e/FR17.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@ test.describe.serial('Zonemaster test FR17 - [Able to specify delegation paramet
});

test('should have one ns and digest form', async () => {
await expect(page.locator('div[formArrayName] .row')).toHaveCount(2);
await expect(page.locator('div[formArrayName] fieldset')).toHaveCount(2);
await expect(page.locator('input[formControlName="keytag"]')).toHaveCount(1);
await expect(page.locator('input[formControlName="ns"]')).toHaveCount(1);
});

test('should be possible to add new ns form', async () => {
await page.locator('div[formArrayName="nameservers"] .row:first-child .btn.add').click();
await page.locator('input[formControlName="ns"]').first().type('test');
await expect(page.locator('input[formControlName="ns"]')).toHaveCount(2);
await expect(page.locator('input[formControlName="keytag"]')).toHaveCount(1);
});

test('should be possible to add new digest form', async () => {
await page.locator('div[formArrayName="ds_info"] .row:first-child .btn.add').click();
await page.locator('input[formControlName="keytag"]').first().type('1234');
await expect(page.locator('input[formControlName="ns"]')).toHaveCount(2);
await expect(page.locator('input[formControlName="keytag"]')).toHaveCount(2);
});

test('should be possible to delete ns forms', async () => {
await page.locator('div[formArrayName="nameservers"] .row:first-child .btn.delete').click();
await page.locator('div[formArrayName="nameservers"] fieldset:first-child button.delete').click();
await expect(page.locator('input[formControlName="ns"]')).toHaveCount(1);
await expect(page.locator('input[formControlName="keytag"]')).toHaveCount(2);
});
Expand Down
2 changes: 1 addition & 1 deletion e2e/FR18.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ test.describe('Zonemaster test FR18 - [The GUI should be able to run tests by ju

test('should display progress bar', async ({ page }) => {
await expect(page.locator('.progress-bar')).toBeHidden();
await page.locator('#input_domain_form').type('progress.afNiC.Fr');
await page.locator('#input-domain-form').type('progress.afNiC.Fr');
await page.locator('div button.launch').click();
await expect(page.locator('.progress-bar')).toBeVisible({ timeout: 10000});
});
Expand Down
4 changes: 2 additions & 2 deletions e2e/FR19.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ test.describe('Zonemaster test FR19 - [The GUI should be able to run the test wi

test('should NOT display progress bar when we add a NS ip', async ({ page }) => {
await expect(page.locator('.progress-bar')).toBeHidden();
await page.locator('#input_domain_form').type('progress.afNiC.Fr');
await page.locator('#input-domain-form').type('progress.afNiC.Fr');
await page.locator('input[formControlName="ip"]').type('192.134.4.1');
await page.locator('div button.launch').click();

Expand All @@ -28,7 +28,7 @@ test.describe('Zonemaster test FR19 - [The GUI should be able to run the test wi

test('should display progress bar when we add a NS name', async ({ page }) => {
await expect(page.locator('.progress-bar')).toBeHidden();
await page.locator('#input_domain_form').type('progress.afNiC.Fr');
await page.locator('#input-domain-form').type('progress.afNiC.Fr');
await page.locator('input[formControlName="ns"]').type('ns1.nic.fr');
await page.locator('div button.launch').click();
await expect(page.locator('.progress-bar')).toBeVisible({ timeout: 10000 });
Expand Down
10 changes: 5 additions & 5 deletions e2e/FR20.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ test.describe('Zonemaster test FR20 - [The user must be able to submit one or mo
test('should display progress bar when we add a DS entry and launch a test', async ({ page }) => {
await expect(page.locator('.progress-bar')).toBeHidden();

await page.locator('#input_domain_form').type('progress.afNiC.Fr');
await page.locator('#input-domain-form').type('progress.afNiC.Fr');

await page.locator('input[formControlName="keytag"]').type('37610');
await page.locator('input[formControlName="digest"]').type('d2681e301f632bd76544e6d5b6631a12d97b5479ff07cd24efecd19203c77db3');
await page.locator('input[formControlName="keytag"]').first().type('37610');
await page.locator('input[formControlName="digest"]').first().type('d2681e301f632bd76544e6d5b6631a12d97b5479ff07cd24efecd19203c77db3');

await page.locator('select[formControlName="algorithm"]').selectOption({ label: '8 - RSASHA256'});
await page.locator('select[formControlName="digtype"]').selectOption({ label: '2 - SHA-256'});
await page.locator('select[formControlName="algorithm"]').first().selectOption({ label: '8 - RSASHA256'});
await page.locator('select[formControlName="digtype"]').first().selectOption({ label: '2 - SHA-256'});

await page.locator('div button.launch').click();
await expect(page.locator('.progress-bar')).toBeVisible({ timeout: 10000 });
Expand Down
Loading

0 comments on commit 73fc1e3

Please sign in to comment.