Skip to content
Closed
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 package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@qawolf/pom",
"version": "0.6.1",
"version": "0.6.2",
"private": false,
"license": "MIT",
"repository": {
Expand Down
66 changes: 65 additions & 1 deletion src/entryPointPageObject.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { describe, expect, it, jest } from "@jest/globals";
import { afterEach, describe, expect, it, jest } from "@jest/globals";
import type {
Browser,
BrowserContext,
Expand Down Expand Up @@ -270,6 +270,70 @@ describe("[CI] EntryPointPageObject browser launch", () => {
});
});

describe("[CI] initializeBrowser — extra HTTP header from env", () => {
const originalEnv = { ...process.env };

afterEach(() => {
process.env = { ...originalEnv };
});

it("sends nothing extra when only one of the two env vars is set", async () => {
makeFakeContext();
delete process.env.EXTRA_HTTP_HEADER_NAME;
process.env.EXTRA_HTTP_HEADER_VALUE = "some-token";

await PlainEntry.create();

const launched = launch.mock.calls[0]?.[0] as
{ extraHTTPHeaders?: Record<string, string> } | undefined;
expect(launched?.extraHTTPHeaders).toBeUndefined();
});

it("adds the header named by EXTRA_HTTP_HEADER_NAME when both are set", async () => {
makeFakeContext();
process.env.EXTRA_HTTP_HEADER_NAME = "X-Gym-Auth";
process.env.EXTRA_HTTP_HEADER_VALUE = "dGVzdGVyOnMzY3JldA==";

await PlainEntry.create();

expect(launch).toHaveBeenCalledWith(
expect.objectContaining({
extraHTTPHeaders: { "X-Gym-Auth": "dGVzdGVyOnMzY3JldA==" },
}),
);
});

it("merges with, rather than replaces, a flow's own extraHTTPHeaders", async () => {
makeFakeContext();
process.env.EXTRA_HTTP_HEADER_NAME = "X-Gym-Auth";
process.env.EXTRA_HTTP_HEADER_VALUE = "token";

await PlainEntry.create({ extraHTTPHeaders: { "app-shell": "true" } });

expect(launch).toHaveBeenCalledWith(
expect.objectContaining({
extraHTTPHeaders: { "app-shell": "true", "X-Gym-Auth": "token" },
}),
);
});

it("lets the flow's own header of the same name win", async () => {
makeFakeContext();
process.env.EXTRA_HTTP_HEADER_NAME = "X-Gym-Auth";
process.env.EXTRA_HTTP_HEADER_VALUE = "env-token";

await PlainEntry.create({
extraHTTPHeaders: { "X-Gym-Auth": "flow-token" },
});

expect(launch).toHaveBeenCalledWith(
expect.objectContaining({
extraHTTPHeaders: { "X-Gym-Auth": "flow-token" },
}),
);
});
});

describe("[CI] initializeBrowser — declared hooks", () => {
it("shields cssSelector popups with one init script on the context", async () => {
const { initScripts, pages } = makeFakeContext();
Expand Down
25 changes: 25 additions & 0 deletions src/entryPointPageObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ function optionalHttpCredentialsFromEnv():
return {};
}

/**
* A single extra request header from the environment, for sites gated by a
* custom auth header instead of HTTP Basic auth (which occupies
* `Authorization` — not an option when the site under test needs that
* header for its own auth). Only applied when both `EXTRA_HTTP_HEADER_NAME`
* and `EXTRA_HTTP_HEADER_VALUE` are non-empty, for the same reason empty
* `AUTH_USERNAME`/`AUTH_PASSWORD` above are skipped rather than sent empty.
*/
function optionalExtraHttpHeaderFromEnv(): Record<string, string> | undefined {
const name = process.env.EXTRA_HTTP_HEADER_NAME;
const value = process.env.EXTRA_HTTP_HEADER_VALUE;
if (name && value) return { [name]: value };

return undefined;
}

/**
* Names are unique within one source so that `allowPopups` / `allowRoutes`
* and same-name replacement are unambiguous. Across sources a repeat is
Expand Down Expand Up @@ -163,9 +179,18 @@ export abstract class EntryPointPageObject extends BasePageObject {
kind: "route",
});

const extraHttpHeaderFromEnv = optionalExtraHttpHeaderFromEnv();
const launchResult = await launch({
...launchOptions,
...optionalHttpCredentialsFromEnv(),
...(extraHttpHeaderFromEnv
? {
extraHTTPHeaders: {
...extraHttpHeaderFromEnv,
...launchOptions.extraHTTPHeaders,
},
}
: {}),
});

if (!("browser" in launchResult))
Expand Down
Loading