Skip to content

Commit 2f93a8e

Browse files
authored
Merge pull request #124 from sanason/integration-tests
Add more integration tests.
2 parents e7c7bfc + 49622ea commit 2f93a8e

14 files changed

Lines changed: 724 additions & 47 deletions

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
FROM nginx
2+
COPY test_site Universal-Federated-Analytics-Min.js Federated.js.map /usr/share/nginx/html/

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,10 @@ Only Digital Analytics Program staff have been granted write access to this repo
110110

111111
### Local development
112112

113-
#### Prerequistites
113+
#### Prerequisites
114114

115115
* NodeJS > v20.x
116+
* Docker
116117

117118
#### Install dependencies
118119

@@ -129,6 +130,13 @@ npm run lint
129130
```
130131

131132
#### Run integration tests
133+
Start up the test site at http://localhost:8080/:
134+
135+
```bash
136+
npm run test-site
137+
```
138+
139+
Then run the tests against the test site:
132140

133141
```bash
134142
npm run cucumber
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Feature: Downloads are reported to DAP when autotracking is enabled
2+
3+
Background:
4+
Given I load an empty browser
5+
And DAP is configured for agency "GSA"
6+
7+
Scenario: User clicks to download file with autotracker on
8+
Given DAP is configured with autotracking enabled
9+
When I load the test site
10+
And I click on a file to download it
11+
Then the file download is reported to DAP with interaction type "mouse click"
12+
13+
Scenario: User presses Enter to download file with autotracker on
14+
Given DAP is configured with autotracking enabled
15+
When I load the test site
16+
And I highlight and press Enter on a file to download it
17+
Then the file download is reported to DAP with interaction type "enter key keystroke"
18+
19+
Scenario: User clicks to download file with autotracker off
20+
Given DAP is configured with autotracking disabled
21+
When I load the test site
22+
And I click on a file to download it
23+
Then the file download is not reported to DAP

features/basic_page_load.feature

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
Feature: Test a basic page with DAP code loaded
1+
Feature: Test the outgoing requests sent by a basic page with DAP code loaded
22

33
Background:
44
Given I load an empty browser
55
And I set the browser to intercept outbound requests
6+
And DAP is configured for agency "GSA"
67

78
Scenario: Loading the page with the DAP code without further action
8-
When I set the page content with "static_page_with_dap.html" HTML file
9-
Then there are no unexpected requests
9+
When I load the test site
10+
And I wait 5 seconds
11+
Then there is a GA4 request
12+
But there are no unexpected requests
1013

1114
Scenario: Loading the page with the DAP code and clicking a button
12-
When I set the page content with "static_page_with_dap.html" HTML file
13-
And I click on element with selector "#test-button"
14-
Then there are no unexpected requests
15+
When I load the test site
16+
And I click on element with selector "#banner-button"
17+
And I wait 5 seconds
18+
Then there is a GA4 request
19+
But there are no unexpected requests

features/configuration.feature

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Feature: A site can load the DAP code with varying levels of customization
2+
3+
Background:
4+
Given I load an empty browser
5+
6+
Scenario: Load a DAP-enabled page with agency and subagency
7+
Given DAP is configured for agency "HHS"
8+
And DAP is configured for subagency "CDC"
9+
When I load the test site
10+
Then DAP will set custom dimensions
11+
| agency | HHS |
12+
| subagency | CDC |
13+
14+
Scenario: Load a DAP-enabled page with agency and site topic and site platform
15+
Given DAP is configured for agency "GSA"
16+
And DAP is configured with site topic "Analytics"
17+
And DAP is configured with site platform "Cloud.gov"
18+
When I load the test site
19+
Then DAP will set custom dimensions
20+
| agency | GSA |
21+
| site_topic | analytics |
22+
| site_platform | cloud.gov |

features/support/dapconfig.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class DAPConfig {
2+
agency;
3+
subagency;
4+
sitetopic;
5+
siteplatform;
6+
autotracker;
7+
cto;
8+
9+
constructor(agency) {
10+
this.agency = agency;
11+
}
12+
13+
toQueryParams() {
14+
const configuredFields = Object.entries(this).filter(entry => entry[1] !== undefined);
15+
return new URLSearchParams(configuredFields).toString();
16+
}
17+
}
18+
19+
export default DAPConfig;

features/support/static_page_with_dap.html

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
import { Given, When, Then } from "@cucumber/cucumber";
22
import puppeteer from 'puppeteer';
3-
import path from 'path';
43
import * as chai from 'chai'
5-
import * as fs from 'fs'
64
const expect = chai.expect;
75

8-
import { fileURLToPath } from 'url';
9-
import { dirname } from 'path';
10-
const __filename = fileURLToPath(import.meta.url);
11-
const __dirname = dirname(__filename);
12-
136
function delay(milliseconds) {
147
return new Promise((resolve) => {
158
setTimeout(resolve, milliseconds);
@@ -36,23 +29,18 @@ Given("I set the browser to intercept outbound requests", async function () {
3629
})
3730
});
3831

39-
When("I set the page content with {string} HTML file", async function (fileName) {
40-
await this.page.setContent(fs.readFileSync(path.join(__dirname, `..`, fileName), 'utf8'));
32+
When("I wait {int} seconds", async function (delaySeconds) {
33+
await delay(delaySeconds * 1000);
4134
});
4235

43-
// This is still in progress. GA requests don't currently occur after clicking a button element.
44-
When("I click on element with selector {string}", async function (elementSelector) {
45-
await this.page.locator(elementSelector).click();
46-
await delay(2000)
47-
})
36+
Then("there is a GA4 request", function() {
37+
const ga4Request = this.requests.find(request => request.url.includes("https://www.google-analytics.com/g/collect"));
38+
expect(ga4Request).to.exist;
39+
});
4840

4941
Then("there are no unexpected requests", function () {
50-
this.requests.forEach((request) => {
51-
let isAllowed = false;
52-
if (request.url.includes('https://dap.digitalgov.gov/Universal-Federated-Analytics-Min.js') || request.url.includes("https://www.googletagmanager.com/gtag/js?id=G-CSLL4ZEK4L")) {
53-
isAllowed = true;
54-
}
55-
expect(isAllowed).to.equal(true)
56-
})
57-
})
58-
42+
const requestUrls = this.requests.map((request) => {
43+
return (new URL(request.url)).host;
44+
});
45+
expect(["localhost:8080", "www.googletagmanager.com", "www.google-analytics.com"]).to.include.members(requestUrls);
46+
})
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Then } from "@cucumber/cucumber";
2+
import * as chai from 'chai'
3+
const expect = chai.expect;
4+
5+
Then("DAP will set custom dimensions", async function (table) {
6+
const configCommand = await this.page.evaluate(() => {
7+
return window.dataLayer.find(item => item[0] === 'config');
8+
});
9+
expect(configCommand["0"]).to.equal("config");
10+
expect(configCommand["1"]).to.equal("G-9TNNMGP8WJ");
11+
expect(configCommand["2"]).to.include(table.rowsHash());
12+
});
13+
14+
Then("the file download is reported to DAP with interaction type {string}", async function (interactionType) {
15+
const event = await this.page.evaluate(() => {
16+
return window.dataLayer.find(item => item[0] === 'event' && item[1] === 'file_download');
17+
});
18+
expect(event).to.deep.equal(
19+
{
20+
'0': 'event',
21+
'1': 'file_download',
22+
'2': {
23+
"interaction_type": interactionType,
24+
"send_to": 'GSA_GA4_ENOR0',
25+
"event_name_dimension": 'file_download',
26+
"file_extension": "zip",
27+
"file_name": "/about.zip",
28+
"link_domain": "localhost",
29+
"link_id": "internaldownload",
30+
"link_text": "/about.zip",
31+
"link_url": "http://localhost:8080/about.zip",
32+
}
33+
}
34+
);
35+
});
36+
37+
Then("the file download is not reported to DAP", async function () {
38+
const event = await this.page.evaluate(() => {
39+
return window.dataLayer.find(item => item[0] === 'event' && item[1] === 'file_download');
40+
});
41+
expect(event).to.be.undefined;
42+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { When } from "@cucumber/cucumber";
2+
3+
When("I click on a file to download it", async function () {
4+
await this.page.locator('#internalDownload').click();
5+
});
6+
7+
When("I highlight and press Enter on a file to download it", async function () {
8+
await this.page.focus('#internalDownload');
9+
await this.page.keyboard.press('Enter');
10+
});
11+
12+
When("I click on element with selector {string}", async function (elementSelector) {
13+
await this.page.locator(elementSelector).click();
14+
});

0 commit comments

Comments
 (0)