Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make siteID mandatory #112

Merged
merged 4 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .changeset/itchy-pens-return.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
"@siteimprove/alfa-test-utils": minor
---

**Added:** `SIP.upload` now accepts an optional `siteID` parameter.
**Breaking:** `SIP.upload` now requires a `siteID` parameter.

This should be the site ID of your site in the Siteimprove Intelligence Platform. It can be use to group tests by site and generate more accurate metadata and aggregates.
This should be the site ID of your site in the Siteimprove Intelligence Platform. It is used to group tests by site and generate more accurate metadata and aggregates.
34 changes: 25 additions & 9 deletions packages/alfa-test-utils/docs/usage/reporting/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ const pageReportURL = Audit.run(alfaPage, {
rules: { include: Rules.aaFilter },
}).then((alfaResult) => {
SIP.upload(alfaResult, {
userName: process.env.SI_USER_NAME!,
apiKey: process.env.SI_API_KEY!,
userName: process.env.SI_USER_NAME, // email address of the user.
apiKey: process.env.SI_API_KEY, // API key generated in the platform.
siteID: "123456", // Site ID from the Siteimprove Intelligence Platform.
testName: (gitInfo) =>
`WCAG 2.2 Level AA conformance test on ${gitInfo.branch}`,
});
Expand All @@ -28,9 +29,11 @@ const pageReportURL = Audit.run(alfaPage, {
rules: { include: Rules.comnponentFilter },
}).then((alfaResult) => {
SIP.upload(alfaResult, {
userName: process.env.SI_USER_NAME!,
apiKey: process.env.SI_API_KEY!,
pageTitle: (alfaPage) =>
userName: process.env.SI_USER_NAME, // email address of the user.
apiKey: process.env.SI_API_KEY, // API key generated in the platform.
siteID: "123456", // Site ID from the Siteimprove Intelligence Platform.
pageTitle: // Gets the text content of the first `<h1>` element.
(alfaPage) =>
Query.getElementDescendants(alfaPage.document)
.filter(Element.isElement)
.find(Element.hasName("h1"))
Expand All @@ -41,10 +44,23 @@ const pageReportURL = Audit.run(alfaPage, {
```

### Cypress
When using Cypress, a function like this one cannot be passed around between the Cypress world and NodeJS because it is not serialisable (it includes some dependencies). This function could, however, live fully within the `cypress.config.ts` file, in which case it must be shared by all test cases (or a more flexible Cypress task must be written).

## Providing a page URL
When using Cypress, a function like this one cannot be passed around between the Cypress world and NodeJS because it is not serialisable (it includes some dependencies). This function could, however, live fully within the `cypress.config.ts` file, in which case it must be shared by all test cases (or a more flexible Cypress task must be written).

> **Note:** Page URLs are currently not displayed in the reports. Thus this documentation is rather short.
## Building a page URL

The `SIP.upload` function also accept a `pageURL` option. It can typically be used to override `localhost` URLs that are frequent in the context of testing but not necessarily meaningful in a report. Like `pageTitle`, the `pageURL` can be a hard-coded `string` or a function generating it from the Alfa page.
The page URL can also be built from the (Alfa representation of the) page:

```typescript
const pageReportURL = Audit.run(alfaPage, {
rules: { include: Rules.comnponentFilter },
}).then((alfaResult) => {
SIP.upload(alfaResult, {
userName: process.env.SI_USER_NAME, // email address of the user.
apiKey: process.env.SI_API_KEY, // API key generated in the platform.
siteID: "123456", // Site ID from the Siteimprove Intelligence Platform.
pageURL: (alfaPage) =>
alfaPage.response.url.toString().replace("localhost:8080", "example.com"),
});
});
```
20 changes: 15 additions & 5 deletions packages/alfa-test-utils/docs/usage/reporting/basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,23 @@ Then, simply use the `SIP.upload` function on the audit result, providing the Si
import { SIP } from "@siteimprove/alfa-test-utils";

const pageReportURL = await SIP.upload(alfaResult, {
userName: process.env.SI_USER_NAME!, // email address of the user.
apiKey: process.env.SI_API_KEY!, // API key generated in the platform.
userName: process.env.SI_USER_NAME, // email address of the user.
apiKey: process.env.SI_API_KEY, // API key generated in the platform.
siteID: "123456", // Site ID from the Siteimprove Intelligence Platform.
});
```

This returns a URL to a Siteimprove Intelligence Platform page report showing the audit results, embedded within a [`Result` object](https://github.com/Siteimprove/alfa/blob/main/docs/api/alfa-result.md) to handle errors, use `console.log(pageReportURL.getOrElse(() => pageReportURL.getErrUnsafe()));` to show its value.

> **Note:** Siteimprove recommends that you include some basic information about the latest commit together with the upload, at least the branch name. This opens possibilities of grouping and reporting based on it, e.g. to follow the number of issues in a given branch. See [common configuration](./configuration.md#including-commit-information) for more information.
### Recommended usage

See [common configuration](./configuration.md#including-commit-information) for more information on these options.

* The `userName`, `apiKey`, and `siteID` parameters are mandatory. If they are missing, the upload will fail and return an error message.
* Credentials (`userName` and `apiKey`) should be treated as any other credentials. Do not write them in plain text, especially if using a versioning system. Prefer using environment variables or CI/CD secrets.
* We strongly recommend adding a minimal `commitInformation: { BranchName: "branch-name" }`.
* The Accessibility Code Checker tries to grab reasonable defaults for `pageTitle` and `pageURL`, but this is not always doable. In case of doubt, provide them explicitly.
* The `testName` is only displayed in the Page Report.

## Pretty printing results in the console

Expand Down Expand Up @@ -57,8 +66,9 @@ export default defineConfig({
on("task", {
async report(audit: Audit.JSON): Promise<null> {
const pageReportUrl = await SIP.upload(audit, {
userName: process.env.SI_USER_EMAIL,
apiKey: process.env.SI_API_KEY,
userName: process.env.SI_USER_NAME, // email address of the user.
apiKey: process.env.SI_API_KEY, // API key generated in the platform.
siteID: "123456", // Site ID from the Siteimprove Intelligence Platform.
});

Logging.fromAudit(audit, pageReportUrl).print();
Expand Down
93 changes: 53 additions & 40 deletions packages/alfa-test-utils/docs/usage/reporting/configuration.md
Original file line number Diff line number Diff line change
@@ -1,92 +1,105 @@
# Configuring the reports (uploads)

This page shows some common set up for configuring what is [uploaded to Siteimprove Intelligence Platform](./basic.md#uploading-results-to-the-siteimprove-intelligence-platform) and how the results are shown in the Page Report. All options described here can be combined together in the same call.
This page shows some common set up for configuring what is [uploaded to Siteimprove Intelligence Platform](./basic.md#uploading-results-to-the-siteimprove-intelligence-platform) and how the results are shown in the Page Report. All options described here can be combined in the same call.

## Including a test name
## Mandatory options

The `SIP.upload` function accepts a test name. This will be displayed in the header of the page report and can be used to separate tests:
The `SIP.upload` function requires an `userName`, `apiKey` and `siteID` parameters. If they any of them is missing, the upload will fail and the function will return an `Err` object with a text message listing the missing value.

While the `siteID` associates the run to a regular site inside the Siteimprove Intelligence Platform, the results of the Accessibility Code Checker and regular crawls do not impact each other and are kept separate (e.g., the DCI score of the live site is **not impacted** by any Accessibility Code Checker run).

## Including commit information

Siteimprove recommends that you include some basic information about the latest commit together with the upload, at least the branch name. This opens possibilities of grouping and reporting based on it, e.g. to follow the number of issues in a given branch.

```typescript
const pageReportURL = Audit.run(alfaPage, {
rules: { include: Rules.aaFilter },
}).then((alfaResult) => {
SIP.upload(alfaResult, {
userName: process.env.SI_USER_NAME!,
apiKey: process.env.SI_API_KEY!,
testName: "WCAG 2.2 Level AA conformance test",
userName: process.env.SI_USER_NAME, // email address of the user.
apiKey: process.env.SI_API_KEY, // API key generated in the platform.
siteID: "123456", // Site ID from the Siteimprove Intelligence Platform.
commitInformation: {
BranchName: "main",
CommitHash: "a1b2c3d4",
},
});
});
```

If not provided, the test name will default to "Accessibility Code Checker".

## Including a page title
See [the `CommitInforation` API](https://github.com/Siteimprove/alfa-integrations/blob/main/docs/api/alfa-test-utils.commitinformation.md) for all the allowed properties, only `BranchName` is mandatory.

Similarly, a page title can be provided and displayed in the Page Report. If none is provided, it will default to the first `<title>` element of the audited page (if any) or to "Unnamed page". It can be convenient to override it typically when testing "single component" pages of design systems.
If running from a `git` repository (in a NodeJS environment), this commit information can be extracted automatically:

```typescript
import { getCommitInformation } from "@siteimprove/alfa-test-utils/git.js";

const gitInformation = await getCommitInformation();

const pageReportURL = Audit.run(alfaPage, {
rules: { include: Rules.componentFilter },
rules: { include: Rules.aaFilter },
}).then((alfaResult) => {
SIP.upload(alfaResult, {
userName: process.env.SI_USER_NAME!,
apiKey: process.env.SI_API_KEY!,
pageTitle: "Paginated table component",
userName: process.env.SI_USER_NAME, // email address of the user.
apiKey: process.env.SI_API_KEY, // API key generated in the platform.
siteID: "123456", // Site ID from the Siteimprove Intelligence Platform.
commitInformation: gitInformation,
});
});
```

## Including the site ID
## Including a page title

If you are testing a page that belongs to a specific site in the Siteimprove Intelligence Platform, you can provide the site ID. This will help produce better metadata and aggregates.
Similarly, a page title can be provided and will be used to group runs of the Accessibility Code Checker in the dashboards. If none is provided, it will default to the first `<title>` element of the audited page (if any) or to "Unnamed page". It can be convenient to override it typically when testing "single component" pages of design systems.

```typescript
const pageReportURL = Audit.run(alfaPage, {
rules: { include: Rules.aaFilter },
rules: { include: Rules.componentFilter },
}).then((alfaResult) => {
SIP.upload(alfaResult, {
userName: process.env.SI_USER_NAME!,
apiKey: process.env.SI_API_KEY!,
siteId: "123456",
userName: process.env.SI_USER_NAME, // email address of the user.
apiKey: process.env.SI_API_KEY, // API key generated in the platform.
siteID: "123456", // Site ID from the Siteimprove Intelligence Platform.
pageTitle: "Paginated table component",
});
});
```

## Including commit information
## Including a page URL

Siteimprove recommends that you include some basic information about the latest commit together with the upload, at least the branch name. This opens possibilities of grouping and reporting based on it, e.g. to follow the number of issues in a given branch.
The URL at which the tested pages live may often be a `localhost` URL or similar temporary development server. By providing a `pageURL` matching the one of the actual page (once it will be published), Siteimprove can connect the test run to the actual page (for example to automatically determine page groups, …)

As for `siteID`, regular crawls and Accessibility Code Checker runs do not impact each other.

```typescript
const pageReportURL = Audit.run(alfaPage, {
rules: { include: Rules.aaFilter },
}).then((alfaResult) => {
// testing a page on a local server at `http://localhost:8080/about-us.html` from the `contact` repository.

const pageReportURL = Audit.run(alfaPage).then((alfaResult) => {
SIP.upload(alfaResult, {
userName: process.env.SI_USER_NAME!,
apiKey: process.env.SI_API_KEY!,
commitInformation: {
BranchName: "main",
CommitHash: "a1b2c3d4",
},
userName: process.env.SI_USER_NAME, // email address of the user.
apiKey: process.env.SI_API_KEY, // API key generated in the platform.
siteID: "123456", // Site ID from the Siteimprove Intelligence Platform.
pageURL: "http://example.com/contact/about-us.html",
});
});
```

See [the `CommitInforation` API](https://github.com/Siteimprove/alfa-integrations/blob/main/docs/api/alfa-test-utils.commitinformation.md) for all the allowed properties, only `BranchName` is mandatory.
## Including a test name

If running from a `git` repository (in a NodeJS environment), this commit information can be extracted automatically:
The `SIP.upload` function accepts a test name. This will be displayed in the header of the page report and can be used to separate tests:

```typescript
import { getCommitInformation } from "@siteimprove/alfa-test-utils/git.js";

const gitInformation = await getCommitInformation();

const pageReportURL = Audit.run(alfaPage, {
rules: { include: Rules.aaFilter },
}).then((alfaResult) => {
SIP.upload(alfaResult, {
userName: process.env.SI_USER_NAME!,
apiKey: process.env.SI_API_KEY!,
commitInformation: gitInformation,
userName: process.env.SI_USER_NAME, // email address of the user.
apiKey: process.env.SI_API_KEY, // API key generated in the platform.
siteID: "123456", // Site ID from the Siteimprove Intelligence Platform.
testName: "WCAG 2.2 Level AA conformance test",
});
});
```

If not provided, the test name will default to "Accessibility Code Checker".
34 changes: 28 additions & 6 deletions packages/alfa-test-utils/src/report/sip.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Array } from "@siteimprove/alfa-array";
import { Element, Query } from "@siteimprove/alfa-dom";
import { Map } from "@siteimprove/alfa-map";
import { Option } from "@siteimprove/alfa-option";
import { None, Option } from "@siteimprove/alfa-option";
import { Err, Ok } from "@siteimprove/alfa-result";
import type { Result } from "@siteimprove/alfa-result";
import type { Thunk } from "@siteimprove/alfa-thunk";
Expand Down Expand Up @@ -58,12 +58,24 @@ export namespace SIP {
options: Options,
override: { url?: string; timestamp?: string; HttpsAgent?: HttpsAgent } = {}
): Promise<Result<string, string>> {
const missing: Array<string> = [];

if (options.userName === undefined) {
return Err.of("Missing user name for Siteimprove Intelligence Platform");
missing.push("User name");
}

if (options.apiKey === undefined) {
return Err.of("Missing API key for Siteimprove Intelligence Platform");
missing.push("API key");
}

if (options.siteID === undefined) {
missing.push("Site ID");
}

if (missing.length > 0) {
return Err.of(
`The following mandatory options are missing: ${missing.join(", ")}`
);
}

const config = await Metadata.axiosConfig(audit, options, override);
Expand Down Expand Up @@ -217,10 +229,20 @@ export namespace SIP {
options: Partial<Options>,
timestamp: string
): Promise<Payload> {
let thePage: Option<Page> = None;

const page: Thunk<Page> = () =>
Page.isPage(audit.page)
? audit.page
: Page.from(audit.page).getUnsafe("Could not deserialize the page");
thePage.getOrElse(() => {
thePage = Option.of(
Page.isPage(audit.page)
? audit.page
: Page.from(audit.page).getUnsafe(
"Could not deserialize the page"
)
);

return thePage.getUnsafe("Could not retrieve the page");
});

const url = options.pageURL ?? page().response.url.toString();
const PageUrl = typeof url === "string" ? url : url(page());
Expand Down
14 changes: 14 additions & 0 deletions packages/alfa-test-utils/test/report/sip.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ test(".upload connects to Siteimprove Intelligence Platform", async (t) => {
const actual = await SIP.upload(makeAudit({ page }), {
userName: "[email protected]",
apiKey: "bar",
siteID: "12345",
});

t.deepEqual(actual.toJSON(), { type: "ok", value: "a page report URL" });
Expand All @@ -391,6 +392,7 @@ test(".upload returns an error on missing user name", async (t) => {

const actual = await SIP.upload(makeAudit({ page }), {
apiKey: "bar",
siteID: "12345",
});

t(actual.isErr());
Expand All @@ -401,6 +403,18 @@ test(".upload returns an error on missing API key", async (t) => {

const actual = await SIP.upload(makeAudit({ page }), {
userName: "[email protected]",
siteID: "12345"
});

t(actual.isErr());
});

test(".upload returns an error on missing site ID", async (t) => {
const page = makePage(h.document([<span></span>]));

const actual = await SIP.upload(makeAudit({ page }), {
userName: "[email protected]",
apiKey: "bar",
});

t(actual.isErr());
Expand Down
Loading