Skip to content

Commit bf08f6c

Browse files
committed
Add more integration tests.
1 parent e7c7bfc commit bf08f6c

13 files changed

Lines changed: 722 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: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Feature: Downloads are reported to DAP when autotracking is enabled
2+
3+
Background:
4+
Given I load an empty browser
5+
6+
Scenario: User clicks to download file with autotracker on
7+
When I load the test site with autotracker enabled
8+
And I click on a file to download it
9+
Then the file download is reported to DAP with interaction type "mouse click"
10+
11+
Scenario: User presses Enter to download file with autotracker on
12+
When I load the test site with autotracker enabled
13+
And I highlight and press Enter on a file to download it
14+
Then the file download is reported to DAP with interaction type "enter key keystroke"
15+
16+
Scenario: User clicks to download file with autotracker off
17+
When I load the test site with autotracker disabled
18+
And I click on a file to download it
19+
Then the file download is not reported to DAP

features/basic_page_load.feature

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
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
66

77
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
8+
When I load the test site with default DAP parameters
9+
And I wait 5 seconds
10+
Then there is a GA4 request
11+
But there are no unexpected requests
1012

1113
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
14+
When I load the test site with default DAP parameters
15+
And I click on element with selector "#banner-button"
16+
And I wait 5 seconds
17+
Then there is a GA4 request
18+
But there are no unexpected requests

features/configuration.feature

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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 no customization
7+
When I load the test site with default DAP parameters
8+
Then DAP is configured with default parameters
9+
10+
Scenario: Load a DAP-enabled page with customization
11+
When I load the test site with custom DAP parameters
12+
Then DAP is configured with custom parameters

features/support/static_page_with_dap.html

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 12 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);
@@ -27,6 +20,7 @@ Given("I set the browser to intercept outbound requests", async function () {
2720
this.responses = [];
2821

2922
this.page.on('request', (request) => {
23+
console.log(request.url());
3024
this.requests.push({ method: request.method(), headers: request.headers(), url: request.url() });
3125
request.continue();
3226
});
@@ -36,23 +30,18 @@ Given("I set the browser to intercept outbound requests", async function () {
3630
})
3731
});
3832

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'));
33+
When("I wait {int} seconds", async function (delaySeconds) {
34+
await delay(delaySeconds * 1000);
4135
});
4236

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-
})
37+
Then("there is a GA4 request", function() {
38+
const ga4Request = this.requests.find(request => request.url.includes("https://www.google-analytics.com/g/collect"));
39+
expect(ga4Request).to.exist;
40+
});
4841

4942
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-
43+
const requestUrls = this.requests.map((request) => {
44+
return (new URL(request.url)).host;
45+
});
46+
expect(["localhost:8080", "www.googletagmanager.com", "www.google-analytics.com"]).to.include.members(requestUrls);
47+
})
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { Then } from "@cucumber/cucumber";
2+
import * as chai from 'chai'
3+
const expect = chai.expect;
4+
5+
Then("DAP is configured with default parameters", async function () {
6+
const config = await this.page.evaluate(() => {
7+
return window.dataLayer.find(item => item[0] === 'config');
8+
});
9+
expect(config).to.deep.equal(
10+
{
11+
"0": "config",
12+
"1": "G-9TNNMGP8WJ",
13+
"2": {
14+
"cookie_expires": "63072000",
15+
"page_location": "http://localhost:8080/",
16+
"page_title": "DAP test site",
17+
"agency": "HHS",
18+
"site_platform": "unspecified:localhost",
19+
"site_topic": "unspecified:localhost",
20+
"subagency": "LOCALHOST",
21+
"script_source": "http://localhost:8080/universal-federated-analytics-min.js",
22+
"version": "20240712 v8.2 - ga4",
23+
"protocol": "http:",
24+
"using_parallel_tracker": "no"
25+
}
26+
}
27+
);
28+
});
29+
30+
Then("DAP is configured with custom parameters", async function () {
31+
const config = await this.page.evaluate(() => {
32+
return window.dataLayer.find(item => item[0] === 'config');
33+
});
34+
expect(config).to.deep.equal(
35+
{
36+
"0": "config",
37+
"1": "G-9TNNMGP8WJ",
38+
"2": {
39+
"cookie_expires": "15768000",
40+
"page_location": "http://localhost:8080/",
41+
"page_title": "DAP test site",
42+
"agency": "GSA",
43+
"site_platform": "standard-site",
44+
"site_topic": "comp,educ,soc|sm|2023-12-04+(ai+education+and+ai+in+education)",
45+
"subagency": "TTS",
46+
"script_source": "http://localhost:8080/universal-federated-analytics-min.js",
47+
"version": "20240712 v8.2 - ga4",
48+
"protocol": "http:",
49+
"using_parallel_tracker": "no"
50+
}
51+
}
52+
);
53+
});
54+
55+
Then("the file download is reported to DAP with interaction type {string}", async function (interactionType) {
56+
const event = await this.page.evaluate(() => {
57+
return window.dataLayer.find(item => item[0] === 'event' && item[1] === 'file_download');
58+
});
59+
expect(event).to.deep.equal(
60+
{
61+
'0': 'event',
62+
'1': 'file_download',
63+
'2': {
64+
"interaction_type": interactionType,
65+
"send_to": 'GSA_GA4_ENOR0',
66+
"event_name_dimension": 'file_download',
67+
"file_extension": "zip",
68+
"file_name": "/about.zip",
69+
"link_domain": "localhost",
70+
"link_id": "internaldownload",
71+
"link_text": "/about.zip",
72+
"link_url": "http://localhost:8080/about.zip",
73+
}
74+
}
75+
);
76+
});
77+
78+
Then("the file download is not reported to DAP", async function () {
79+
const event = await this.page.evaluate(() => {
80+
return window.dataLayer.find(item => item[0] === 'event' && item[1] === 'file_download');
81+
});
82+
expect(event).to.be.undefined;
83+
});
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+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import {When} from "@cucumber/cucumber";
2+
3+
When("I load the test site with default DAP parameters", async function () {
4+
await this.page.goto("http://localhost:8080?agency=HHS");
5+
});
6+
7+
When("I load the test site with custom DAP parameters", async function () {
8+
await this.page.goto("http://localhost:8080?agency=GSA&Subagency=TTS&sitetopic=comp,educ,soc|sm|2023-12-04 (AI education and AI in education)&siteplatform=standard-site&cto=6");
9+
});
10+
11+
When("I load the test site with autotracker enabled", async function () {
12+
// autotracker enabled by default
13+
await this.page.goto("http://localhost:8080");
14+
});
15+
16+
When("I load the test site with autotracker disabled", async function () {
17+
await this.page.goto("http://localhost:8080?autotracker=false");
18+
});

0 commit comments

Comments
 (0)