mirror of
https://github.com/Kong/insomnia.git
synced 2026-11-03 19:45:33 -05:00
test(insomnia-test): add http-request, cookie and environment specs
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
654897312d
commit
641d924b52
64 files changed
+4307
No files matched your search
@@ -0,0 +1,50 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/cookies`;
|
||||
|
||||
test("Verify Cookie With Mismatched Path Is Not Sent With HTTP Request", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { cookieFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url,
|
||||
});
|
||||
|
||||
const mismatchedCookie = {
|
||||
key: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
domain: "localhost",
|
||||
path: "/foo",
|
||||
};
|
||||
const matchedCookie = {
|
||||
key: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
domain: "localhost",
|
||||
path: "/",
|
||||
};
|
||||
await cookieFlow.link(request, [mismatchedCookie, matchedCookie]);
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
const { cookies } = responseView.body as { cookies: Record<string, string> };
|
||||
expect(cookies).not.toHaveProperty(mismatchedCookie.key);
|
||||
expect(cookies).toMatchObject({ [matchedCookie.key]: matchedCookie.value });
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/cookies`;
|
||||
|
||||
test("Verify Re-Linking Same Cookie Key Overwrites Previous Value", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { cookieFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url,
|
||||
});
|
||||
|
||||
const key = faker.string.alphanumeric(8);
|
||||
const staleValue = faker.string.alphanumeric(8);
|
||||
const freshValue = faker.string.alphanumeric(8);
|
||||
await cookieFlow.link(request, [
|
||||
{ key, value: staleValue, domain: "localhost", path: "/" },
|
||||
]);
|
||||
const cookieList = await cookieFlow.link(request, [
|
||||
{ key, value: freshValue, domain: "localhost", path: "/" },
|
||||
]);
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
const { cookies } = responseView.body as { cookies: Record<string, string> };
|
||||
expect(cookieList.filter((cookie) => cookie.key === key)).toHaveLength(1);
|
||||
expect(cookieList).toMatchObject([{ key, value: freshValue }]);
|
||||
expect(cookies).toMatchObject({ [key]: freshValue });
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/cookies`;
|
||||
|
||||
test("Verify Expired Cookie Is Not Sent With HTTP Request", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { cookieFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url,
|
||||
});
|
||||
|
||||
const expiredCookie = {
|
||||
key: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
domain: "localhost",
|
||||
path: "/",
|
||||
expires: new Date("2000-01-01T00:00:00"),
|
||||
};
|
||||
const activeCookie = {
|
||||
key: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
domain: "localhost",
|
||||
path: "/",
|
||||
};
|
||||
await cookieFlow.link(request, [expiredCookie, activeCookie]);
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
const { cookies } = responseView.body as { cookies: Record<string, string> };
|
||||
expect(cookies).not.toHaveProperty(expiredCookie.key);
|
||||
expect(cookies).toMatchObject({ [activeCookie.key]: activeCookie.value });
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/cookies`;
|
||||
|
||||
test("Verify Linked Cookie Is Sent With HTTP Request", async ({ user }) => {
|
||||
const { cookieFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url,
|
||||
});
|
||||
|
||||
const cookieList = await cookieFlow.link(request, [
|
||||
{
|
||||
key: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
domain: "localhost",
|
||||
path: "/",
|
||||
},
|
||||
{
|
||||
key: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
domain: "localhost",
|
||||
path: "/",
|
||||
},
|
||||
{
|
||||
key: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
domain: "example.org",
|
||||
path: "/",
|
||||
},
|
||||
]);
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
|
||||
const { cookies } = responseView.body as { cookies: Record<string, string> };
|
||||
expect(Object.keys(cookies)).toHaveLength(2);
|
||||
|
||||
const expectedCookies = Object.fromEntries(
|
||||
cookieList
|
||||
.filter((cookie) => cookie.domain === "localhost")
|
||||
.map((cookie) => [cookie.key, cookie.value]),
|
||||
);
|
||||
expect(cookies).toMatchObject(expectedCookies);
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/cookies`;
|
||||
|
||||
test("Verify __Host- Prefixed Cookie Is Only Sent When Marked HostOnly", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { cookieFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url,
|
||||
});
|
||||
|
||||
const hostOnlyCookie = {
|
||||
key: `__Host-${faker.string.alphanumeric(8)}`,
|
||||
value: faker.string.alphanumeric(8),
|
||||
domain: "localhost",
|
||||
path: "/",
|
||||
secure: true,
|
||||
hostOnly: true,
|
||||
};
|
||||
const nonHostOnlyCookie = {
|
||||
key: `__Host-${faker.string.alphanumeric(8)}`,
|
||||
value: faker.string.alphanumeric(8),
|
||||
domain: "localhost",
|
||||
path: "/",
|
||||
secure: true,
|
||||
};
|
||||
await cookieFlow.link(request, [hostOnlyCookie, nonHostOnlyCookie]);
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
const { cookies } = responseView.body as { cookies: Record<string, string> };
|
||||
expect(cookies).toMatchObject({
|
||||
[hostOnlyCookie.key]: hostOnlyCookie.value,
|
||||
});
|
||||
expect(cookies).not.toHaveProperty(nonHostOnlyCookie.key);
|
||||
});
|
||||
@@ -0,0 +1,66 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, HTTP_SERVER_HTTPS, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify HttpOnly Cookie Flag Persists And Cookie Is Always Sent Over HTTP And HTTPS", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { cookieFlow, httpRequestFlow, workspaceFlow, preferencesFlow } =
|
||||
user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
await preferencesFlow.set({ validateSSL: false });
|
||||
|
||||
const httpRequest = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${HTTP_SERVER}/cookies`,
|
||||
});
|
||||
const httpsRequest = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${HTTP_SERVER_HTTPS}/cookies`,
|
||||
});
|
||||
|
||||
const httpOnlyCookie = {
|
||||
key: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
domain: "localhost",
|
||||
path: "/",
|
||||
httpOnly: true,
|
||||
};
|
||||
const cookieList = await cookieFlow.link(httpRequest, [httpOnlyCookie]);
|
||||
|
||||
const httpResponse = await httpRequestFlow.send(httpRequest);
|
||||
const httpsResponse = await httpRequestFlow.send(httpsRequest);
|
||||
|
||||
expect(httpResponse.statusCode).toBe(200);
|
||||
const { cookies: httpCookies } = httpResponse.body as {
|
||||
cookies: Record<string, string>;
|
||||
};
|
||||
expect(httpCookies).toMatchObject({
|
||||
[httpOnlyCookie.key]: httpOnlyCookie.value,
|
||||
});
|
||||
expect(httpsResponse.statusCode).toBe(200);
|
||||
const { cookies: httpsCookies } = httpsResponse.body as {
|
||||
cookies: Record<string, string>;
|
||||
};
|
||||
expect(httpsCookies).toMatchObject({
|
||||
[httpOnlyCookie.key]: httpOnlyCookie.value,
|
||||
});
|
||||
expect(
|
||||
cookieList.find((cookie) => cookie.key === httpOnlyCookie.key)?.httpOnly,
|
||||
).toBe(true);
|
||||
});
|
||||
@@ -0,0 +1,52 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/cookies`;
|
||||
|
||||
test("Verify Editing A Cookie Via The Raw Tab Updates Its Fields And Is Sent", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { cookieFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
const { cookiePage } = user.pageManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url,
|
||||
});
|
||||
|
||||
const key = faker.string.alphanumeric(8);
|
||||
const oldValue = faker.string.alphanumeric(8);
|
||||
const newValue = faker.string.alphanumeric(8);
|
||||
await cookieFlow.link(request, [
|
||||
{ key, value: oldValue, domain: "example.org", path: "/" },
|
||||
]);
|
||||
|
||||
await cookiePage.open();
|
||||
await cookiePage.editCookieRaw(key, `${key}=${newValue}; Domain=localhost; Path=/`);
|
||||
const cookiesWhileOpen = await cookiePage.getCookies();
|
||||
await cookiePage.close();
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
const { cookies: sentCookies } = responseView.body as {
|
||||
cookies: Record<string, string>;
|
||||
};
|
||||
|
||||
expect(cookiesWhileOpen).toMatchObject([
|
||||
{ key, value: newValue, domain: "localhost", path: "/" },
|
||||
]);
|
||||
expect(sentCookies).toEqual({ [key]: newValue });
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, HTTP_SERVER_HTTPS, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify Secure Cookie Is Sent Over HTTPS But Not Over Plain HTTP", async ({
|
||||
user,
|
||||
}) => {
|
||||
test.fail(true, 'INS-3179');
|
||||
|
||||
const { cookieFlow, httpRequestFlow, workspaceFlow, preferencesFlow } =
|
||||
user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
await preferencesFlow.set({ validateSSL: false });
|
||||
|
||||
const httpRequest = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${HTTP_SERVER}/cookies`,
|
||||
});
|
||||
const httpsRequest = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${HTTP_SERVER_HTTPS}/cookies`,
|
||||
});
|
||||
|
||||
const secureCookie = {
|
||||
key: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
domain: "localhost",
|
||||
path: "/",
|
||||
secure: true,
|
||||
};
|
||||
await cookieFlow.link(httpRequest, [secureCookie]);
|
||||
|
||||
const httpsResponse = await httpRequestFlow.send(httpsRequest);
|
||||
expect(httpsResponse.statusCode).toBe(200);
|
||||
const { cookies: httpsCookies } = httpsResponse.body as {
|
||||
cookies: Record<string, string>;
|
||||
};
|
||||
expect(httpsCookies).toMatchObject({
|
||||
[secureCookie.key]: secureCookie.value,
|
||||
});
|
||||
|
||||
const httpResponse = await httpRequestFlow.send(httpRequest);
|
||||
const { cookies: httpCookies } = httpResponse.body as {
|
||||
cookies: Record<string, string>;
|
||||
};
|
||||
expect(httpCookies).not.toHaveProperty(secureCookie.key);
|
||||
});
|
||||
@@ -0,0 +1,68 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { EnvironmentKvPairDataType } from "../../models/environment";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const lowerCaseVariable = "caseVar";
|
||||
const upperCaseVariable = "CaseVar";
|
||||
|
||||
test("Verify Variable Names Are Case Sensitive Across Environment Levels", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { environmentFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const baseValue = faker.string.alphanumeric(10);
|
||||
const subValue = faker.string.alphanumeric(10);
|
||||
|
||||
const baseEnvironment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: lowerCaseVariable,
|
||||
value: baseValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
const subEnvironment = await environmentFlow.createSubEnvironment(baseEnvironment, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: upperCaseVariable,
|
||||
value: subValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
await environmentFlow.link(collection, subEnvironment);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post?lower={{${lowerCaseVariable}}}&upper={{${upperCaseVariable}}}`,
|
||||
} satisfies HttpRequest);
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
args: { lower: baseValue, upper: subValue },
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { EnvironmentKvPairDataType } from "../../models/environment";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const variableA = "a";
|
||||
const variableB = "b";
|
||||
|
||||
test("Verify Circular Variable Reference Resolves To Literal Unresolved Text", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { environmentFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const environment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: variableA,
|
||||
value: `{{${variableB}}}`,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "",
|
||||
name: variableB,
|
||||
value: `{{${variableA}}}`,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
await environmentFlow.link(collection, environment);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post?value={{${variableA}}}`,
|
||||
} satisfies HttpRequest);
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({ args: { value: `{{${variableA}}}` } });
|
||||
});
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { EnvironmentKvPairDataType } from "../../models/environment";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify creating and duplicating a global environment", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { environmentFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const variableValue = faker.string.alphanumeric(10);
|
||||
const environment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: "globalVar",
|
||||
value: variableValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const duplicatedName = faker.string.alphanumeric(10);
|
||||
const duplicatedEnvironment = await workspaceFlow.duplicateEnvironment(
|
||||
environment,
|
||||
duplicatedName,
|
||||
);
|
||||
await environmentFlow.link(collection, {
|
||||
...duplicatedEnvironment,
|
||||
name: "Base Environment",
|
||||
});
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post?value={{ globalVar }}`,
|
||||
} satisfies HttpRequest);
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(duplicatedEnvironment.id).not.toBe(environment.id);
|
||||
expect(duplicatedEnvironment.name).toBe(duplicatedName);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({ args: { value: variableValue } });
|
||||
});
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { EnvironmentKvPairDataType } from "../../models/environment";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const sharedVariable = "shared";
|
||||
|
||||
test("Verify a disabled sub-environment variable falls back to the base environment's value", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { environmentFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const baseValue = faker.string.alphanumeric(10);
|
||||
const subValue = faker.string.alphanumeric(10);
|
||||
|
||||
const base = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: "Base Environment",
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: sharedVariable,
|
||||
value: baseValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
const sub = await environmentFlow.createSubEnvironment(base, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: sharedVariable,
|
||||
value: subValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
await environmentFlow.link(collection, sub);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post?value={{${sharedVariable}}}`,
|
||||
} satisfies HttpRequest);
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({ args: { value: baseValue } });
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { EnvironmentKvPairDataType } from "../../models/environment";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const leafVariable = "leaf";
|
||||
const midVariable = "mid";
|
||||
const topVariable = "top";
|
||||
|
||||
test("Verify Disabled Mid-Chain Variable Leaves Reference Unresolved", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { environmentFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const leafValue = faker.string.alphanumeric(10);
|
||||
|
||||
const environment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: leafVariable,
|
||||
value: leafValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "",
|
||||
name: midVariable,
|
||||
value: `{{${leafVariable}}}`,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: false,
|
||||
},
|
||||
{
|
||||
id: "",
|
||||
name: topVariable,
|
||||
value: `{{${midVariable}}}`,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
await environmentFlow.link(collection, environment);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post?value={{${topVariable}}}`,
|
||||
} satisfies HttpRequest);
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
args: { value: `{{${midVariable}}}` },
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { test } from "../../misc/fixtures";
|
||||
import type {
|
||||
EnvironmentKvPairData} from "../../models/environment";
|
||||
import {
|
||||
EnvironmentKvPairDataType,
|
||||
} from "../../models/environment";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify Environment Raw JSON Editor Reads Back And Persists Edits", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { environmentFlow, workspaceFlow } = user.flowManager;
|
||||
const { environmentPage } = user.pageManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const varA = {
|
||||
id: "",
|
||||
name: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
} satisfies EnvironmentKvPairData;
|
||||
const environment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [varA],
|
||||
});
|
||||
|
||||
await environmentPage.selectEnvironment(environment.name);
|
||||
await environmentPage.toggleRawEdit();
|
||||
const rawBefore = await environmentPage.getRawJson();
|
||||
|
||||
const newKey = faker.string.alphanumeric(8);
|
||||
const newValue = faker.string.alphanumeric(8);
|
||||
await environmentPage.setRawJson(JSON.stringify({ [newKey]: newValue }));
|
||||
|
||||
await user.page.reload();
|
||||
await environmentPage.selectEnvironment(environment.name);
|
||||
const rawAfterReload = await environmentPage.getRawJson();
|
||||
|
||||
expect(JSON.parse(rawBefore)).toEqual({ [varA.name]: varA.value });
|
||||
expect(JSON.parse(rawAfterReload)).toEqual({ [newKey]: newValue });
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { test } from "../../misc/fixtures";
|
||||
import type {
|
||||
EnvironmentKvPairData} from "../../models/environment";
|
||||
import {
|
||||
EnvironmentKvPairDataType,
|
||||
} from "../../models/environment";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify Environment Table Editor's Blank Row Is Not Persisted And Deleting A Row Leaves No Stale Text", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { environmentFlow, workspaceFlow } = user.flowManager;
|
||||
const { environmentPage } = user.pageManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
|
||||
const varA = {
|
||||
id: "",
|
||||
name: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
} satisfies EnvironmentKvPairData;
|
||||
const varB = {
|
||||
id: "",
|
||||
name: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
} satisfies EnvironmentKvPairData;
|
||||
const varC = {
|
||||
id: "",
|
||||
name: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
} satisfies EnvironmentKvPairData;
|
||||
const environment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [varA, varB, varC],
|
||||
});
|
||||
const beforeDelete = await environmentFlow.get(environment.name);
|
||||
|
||||
await environmentPage.deleteRow(environmentPage.getRow(varB.name));
|
||||
|
||||
const afterDelete = await environmentFlow.get(environment.name);
|
||||
|
||||
expect(beforeDelete?.kvPairData).toEqual([varA, varB, varC]);
|
||||
expect(afterDelete?.kvPairData).toEqual([varA, varC]);
|
||||
});
|
||||
@@ -0,0 +1,63 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { EnvironmentKvPairDataType } from "../../models/environment";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const firstVariable = "a";
|
||||
const secondVariable = "b";
|
||||
|
||||
test("Verify Multiple Variables Mixed In A Single Value Resolve Together", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { environmentFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const firstValue = faker.string.alphanumeric(10);
|
||||
const secondValue = faker.string.alphanumeric(10);
|
||||
|
||||
const environment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: firstVariable,
|
||||
value: firstValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "",
|
||||
name: secondVariable,
|
||||
value: secondValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
await environmentFlow.link(collection, environment);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post?value={{${firstVariable}}}-{{${secondVariable}}}`,
|
||||
} satisfies HttpRequest);
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
args: { value: `${firstValue}-${secondValue}` },
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,67 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { EnvironmentKvPairDataType } from "../../models/environment";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const leafVariable = "leaf";
|
||||
const midVariable = "mid";
|
||||
const topVariable = "top";
|
||||
|
||||
test("Verify Multi-Level Nested Variable Resolution", async ({ user }) => {
|
||||
const { environmentFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const finalValue = faker.string.alphanumeric(10);
|
||||
|
||||
const environment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: leafVariable,
|
||||
value: finalValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "",
|
||||
name: midVariable,
|
||||
value: `{{${leafVariable}}}`,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "",
|
||||
name: topVariable,
|
||||
value: `{{${midVariable}}}`,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await environmentFlow.link(collection, environment);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post?value={{${topVariable}}}`,
|
||||
} satisfies HttpRequest);
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({ args: { value: finalValue } });
|
||||
});
|
||||
@@ -0,0 +1,91 @@
|
||||
import * as crypto from "node:crypto";
|
||||
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ContentType } from "../../enums/content-type";
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import {
|
||||
ENVIRONMENT_TYPE,
|
||||
EnvironmentKvPairDataType,
|
||||
} from "../../models/environment";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const testWithVaultKey = test.extend({
|
||||
vaultKey: async ({}, use) => {
|
||||
const jwk = {
|
||||
alg: "A256GCM",
|
||||
ext: true,
|
||||
k: crypto.randomBytes(32).toString("base64url"),
|
||||
key_ops: ["encrypt", "decrypt"],
|
||||
kty: "oct",
|
||||
};
|
||||
await use(Buffer.from(JSON.stringify(jwk), "utf8").toString("base64"));
|
||||
},
|
||||
vaultSalt: async ({}, use) => {
|
||||
await use(crypto.randomBytes(32).toString("hex"));
|
||||
},
|
||||
});
|
||||
|
||||
testWithVaultKey(
|
||||
"Verify Secret-typed environment variables are stored encrypted and rendered decrypted at send-time",
|
||||
async ({ user }) => {
|
||||
const { environmentFlow, httpRequestFlow, workspaceFlow } =
|
||||
user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const globalEnvironment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
type: ENVIRONMENT_TYPE,
|
||||
});
|
||||
const secretValueFoo = faker.string.alphanumeric(10);
|
||||
const secretValueHello = faker.string.alphanumeric(10);
|
||||
const privateEnvironment = await environmentFlow.createSubEnvironment(globalEnvironment, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
isPrivate: true,
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: "foo",
|
||||
value: secretValueFoo,
|
||||
type: EnvironmentKvPairDataType.SECRET,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "",
|
||||
name: "hello",
|
||||
value: secretValueHello,
|
||||
type: EnvironmentKvPairDataType.SECRET,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
await environmentFlow.link(collection, privateEnvironment);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post`,
|
||||
body: {
|
||||
mimeType: ContentType.Plain,
|
||||
text: "{{ _.vault.foo }}\n{{ _.vault.hello }}",
|
||||
},
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request!);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect((responseView.body as { data: string }).data).toBe(
|
||||
`${secretValueFoo}\n${secretValueHello}`,
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,52 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { EnvironmentKvPairDataType } from "../../models/environment";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const selfVariable = "a";
|
||||
|
||||
test("Verify Self-Referencing Variable Resolves To Literal Unresolved Text", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { environmentFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const environment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: selfVariable,
|
||||
value: `{{${selfVariable}}}`,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
await environmentFlow.link(collection, environment);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post?value={{${selfVariable}}}`,
|
||||
} satisfies HttpRequest);
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
args: { value: `{{${selfVariable}}}` },
|
||||
});
|
||||
});
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { EnvironmentKvPairDataType } from "../../models/environment";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const sharedVariable = "shared";
|
||||
|
||||
test("Verify an empty sub-environment falls back to the base environment until it defines its own value", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { environmentFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
const { environmentPage, workspacePage } = user.pageManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const baseValue = faker.string.alphanumeric(10);
|
||||
const subValue = faker.string.alphanumeric(10);
|
||||
|
||||
const base = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: "Base Environment",
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: sharedVariable,
|
||||
value: baseValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
const sub = await environmentFlow.createSubEnvironment(base, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
});
|
||||
await environmentFlow.link(collection, sub);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post?value={{${sharedVariable}}}`,
|
||||
} satisfies HttpRequest);
|
||||
const beforeOwnValue = await httpRequestFlow.send(request);
|
||||
|
||||
const baseNode = await workspacePage.findItemNode(base);
|
||||
await workspacePage.clickNode(baseNode!);
|
||||
await environmentPage.selectEnvironment(sub.name);
|
||||
await environmentPage.setVariables([
|
||||
{
|
||||
id: "",
|
||||
name: sharedVariable,
|
||||
value: subValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
]);
|
||||
const afterOwnValue = await httpRequestFlow.send(request);
|
||||
|
||||
expect(beforeOwnValue.statusCode).toBe(200);
|
||||
expect(beforeOwnValue.body).toMatchObject({ args: { value: baseValue } });
|
||||
expect(afterOwnValue.statusCode).toBe(200);
|
||||
expect(afterOwnValue.body).toMatchObject({ args: { value: subValue } });
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { EnvironmentKvPairDataType } from "../../models/environment";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const sharedVariable = "shared";
|
||||
|
||||
test("Verify Sub Environment Variable Overrides Base Environment", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { environmentFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const baseValue = faker.string.alphanumeric(10);
|
||||
const subValue = faker.string.alphanumeric(10);
|
||||
|
||||
const baseEnvironment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: sharedVariable,
|
||||
value: baseValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
const subEnvironment = await environmentFlow.createSubEnvironment(baseEnvironment, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: sharedVariable,
|
||||
value: subValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
await environmentFlow.link(collection, subEnvironment);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post?value={{${sharedVariable}}}`,
|
||||
} satisfies HttpRequest);
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({ args: { value: subValue } });
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { test } from "../../misc/fixtures";
|
||||
import type {
|
||||
EnvironmentKvPairData} from "../../models/environment";
|
||||
import {
|
||||
EnvironmentKvPairDataType,
|
||||
} from "../../models/environment";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify Disabling A Row In The Table Editor Is Reflected On Read-Back", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { environmentFlow, workspaceFlow } = user.flowManager;
|
||||
const { environmentPage } = user.pageManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const varA = {
|
||||
id: "",
|
||||
name: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
} satisfies EnvironmentKvPairData;
|
||||
const varB = {
|
||||
id: "",
|
||||
name: faker.string.alphanumeric(8),
|
||||
value: faker.string.alphanumeric(8),
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
} satisfies EnvironmentKvPairData;
|
||||
await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [varA, varB],
|
||||
});
|
||||
|
||||
await environmentPage.disableRow(environmentPage.getRow(varA.name));
|
||||
const variables = await environmentPage.getVariables();
|
||||
|
||||
expect(variables).toEqual([
|
||||
{ ...varA, enabled: false },
|
||||
{ ...varB, enabled: true },
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { MOCK_API_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { EnvironmentKvPairDataType } from "../../models/environment";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const variableName = "unlinked";
|
||||
|
||||
test("Verify Unlinked Environment Variable Causes Error", async ({ user }) => {
|
||||
const { environmentFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: variableName,
|
||||
value: "variable",
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${MOCK_API_SERVER}/{{${variableName}}}`,
|
||||
});
|
||||
await expect(httpRequestFlow.send(request)).rejects.toThrow(
|
||||
/environment variable is missing.*have not been assigned.*unlinked/s,
|
||||
);
|
||||
});
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
import * as crypto from "node:crypto";
|
||||
import path from "node:path";
|
||||
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ProjectType } from "../../../enums/project-types";
|
||||
import { test } from "../../../misc/fixtures";
|
||||
import { Collection } from "../../../models/collection";
|
||||
import {
|
||||
ENVIRONMENT_TYPE,
|
||||
EnvironmentKvPairDataType,
|
||||
} from "../../../models/environment";
|
||||
import { Project } from "../../../models/project";
|
||||
|
||||
const testWithVaultKey = test.extend({
|
||||
vaultKey: async ({}, use) => {
|
||||
const jwk = {
|
||||
alg: "A256GCM",
|
||||
ext: true,
|
||||
k: crypto.randomBytes(32).toString("base64url"),
|
||||
key_ops: ["encrypt", "decrypt"],
|
||||
kty: "oct",
|
||||
};
|
||||
await use(Buffer.from(JSON.stringify(jwk), "utf8").toString("base64"));
|
||||
},
|
||||
vaultSalt: async ({}, use) => {
|
||||
await use(crypto.randomBytes(32).toString("hex"));
|
||||
},
|
||||
});
|
||||
|
||||
testWithVaultKey(
|
||||
"Verify legacy array/object vault environment variables render correctly and a scalar vault value throws the reserved-key error",
|
||||
async ({ user }) => {
|
||||
const { environmentFlow, httpRequestFlow, importFlow, workspaceFlow } =
|
||||
user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const globalEnvironment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
type: ENVIRONMENT_TYPE,
|
||||
});
|
||||
const secretEnvironment = await environmentFlow.createSubEnvironment(globalEnvironment, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
isPrivate: true,
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: "secretKey",
|
||||
value: faker.string.alphanumeric(10),
|
||||
type: EnvironmentKvPairDataType.SECRET,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await importFlow.importFile(
|
||||
project,
|
||||
path.join(__dirname, "vault-legacy-formats.yaml"),
|
||||
);
|
||||
const collection = new Collection("Vault Legacy Format Collection");
|
||||
await environmentFlow.link(collection, secretEnvironment);
|
||||
|
||||
await environmentFlow.activate(collection, "legacy vault value array");
|
||||
const arrayRequest = await httpRequestFlow.get("legacy-array-vault");
|
||||
const arrayResponse = await httpRequestFlow.send(arrayRequest!);
|
||||
|
||||
await environmentFlow.activate(collection, "legacy vault value object");
|
||||
const objectRequest = await httpRequestFlow.get("legacy-object-vault");
|
||||
const objectResponse = await httpRequestFlow.send(objectRequest!);
|
||||
|
||||
await environmentFlow.activate(collection, "base with vault");
|
||||
const invalidRequest = await httpRequestFlow.get("legacy-invalid-vault");
|
||||
|
||||
expect(arrayResponse.statusCode).toBe(200);
|
||||
expect((arrayResponse.body as { data: string }).data).toBe(
|
||||
"vault_array_a\nvault_array_b",
|
||||
);
|
||||
expect(objectResponse.statusCode).toBe(200);
|
||||
expect((objectResponse.body as { data: string }).data).toBe("secv1\nsecv2");
|
||||
await expect(httpRequestFlow.send(invalidRequest!)).rejects.toThrow(
|
||||
/vault is a reserved key for insomnia vault/,
|
||||
);
|
||||
},
|
||||
);
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
_type: export
|
||||
__export_format: 4
|
||||
__export_date: 2025-01-24T07:58:39.196Z
|
||||
__export_source: insomnia.desktop.app:v10.3.1-beta.0
|
||||
resources:
|
||||
- _id: wrk_37e3ee9c2ce7468493378fa5e525b4b1
|
||||
parentId: null
|
||||
modified: 1737705410863
|
||||
created: 1737705410863
|
||||
name: Vault Legacy Format Collection
|
||||
description: ""
|
||||
scope: collection
|
||||
_type: workspace
|
||||
- _id: req_1c9ef3a2afae47d1bd960ae23de09750
|
||||
parentId: wrk_37e3ee9c2ce7468493378fa5e525b4b1
|
||||
modified: 1737617845875
|
||||
created: 1734948333857
|
||||
url: localhost:4060/post
|
||||
name: legacy-array-vault
|
||||
description: ""
|
||||
method: POST
|
||||
body:
|
||||
mimeType: text/plain
|
||||
text: |-
|
||||
{{ _.vault[0] }}
|
||||
{{ _.vault[1] }}
|
||||
headers:
|
||||
- name: Content-Type
|
||||
value: text/plain
|
||||
authentication: {}
|
||||
metaSortKey: -1734948333857
|
||||
isPrivate: false
|
||||
pathParameters: []
|
||||
settingStoreCookies: true
|
||||
settingSendCookies: true
|
||||
settingDisableRenderRequestBody: false
|
||||
settingEncodeUrl: true
|
||||
settingRebuildPath: true
|
||||
settingFollowRedirects: global
|
||||
_type: request
|
||||
- _id: req_fb7fb8d4345f471fb53d03b069737a07
|
||||
parentId: wrk_37e3ee9c2ce7468493378fa5e525b4b1
|
||||
modified: 1737617874271
|
||||
created: 1737617856040
|
||||
url: localhost:4060/post
|
||||
name: legacy-object-vault
|
||||
description: ""
|
||||
method: POST
|
||||
body:
|
||||
mimeType: text/plain
|
||||
text: |-
|
||||
{{ _.vault.v1 }}
|
||||
{{ _.vault.v2 }}
|
||||
headers:
|
||||
- name: Content-Type
|
||||
value: text/plain
|
||||
authentication: {}
|
||||
metaSortKey: -1729018003774
|
||||
isPrivate: false
|
||||
pathParameters: []
|
||||
settingStoreCookies: true
|
||||
settingSendCookies: true
|
||||
settingDisableRenderRequestBody: false
|
||||
settingEncodeUrl: true
|
||||
settingRebuildPath: true
|
||||
settingFollowRedirects: global
|
||||
_type: request
|
||||
- _id: req_2a150b45acb242cfa2db04d929a11085
|
||||
parentId: wrk_37e3ee9c2ce7468493378fa5e525b4b1
|
||||
modified: 1737617920254
|
||||
created: 1737617896390
|
||||
url: localhost:4060/post
|
||||
name: legacy-invalid-vault
|
||||
description: ""
|
||||
method: POST
|
||||
body:
|
||||
mimeType: text/plain
|
||||
text: ""
|
||||
headers:
|
||||
- name: Content-Type
|
||||
value: text/plain
|
||||
authentication: {}
|
||||
metaSortKey: -1731983168815.5
|
||||
isPrivate: false
|
||||
pathParameters: []
|
||||
settingStoreCookies: true
|
||||
settingSendCookies: true
|
||||
settingDisableRenderRequestBody: false
|
||||
settingEncodeUrl: true
|
||||
settingRebuildPath: true
|
||||
settingFollowRedirects: global
|
||||
_type: request
|
||||
- _id: env_40681941450149a4a41f2dcbc22ec616
|
||||
parentId: wrk_37e3ee9c2ce7468493378fa5e525b4b1
|
||||
modified: 1737618683836
|
||||
created: 1732861968102
|
||||
name: Base Environment1
|
||||
data:
|
||||
a_hello: test
|
||||
dataPropertyOrder:
|
||||
"&":
|
||||
- a_hello
|
||||
color: null
|
||||
isPrivate: false
|
||||
metaSortKey: 1732861968102
|
||||
environmentType: kv
|
||||
kvPairData:
|
||||
- id: envPair_62a7e9c0cdb949e0abf15e0fe4b1e8d3
|
||||
name: a_hello
|
||||
value: test
|
||||
type: str
|
||||
enabled: true
|
||||
_type: environment
|
||||
- _id: env_7ace551350dc40cbbb8302234ec0af0a
|
||||
parentId: env_40681941450149a4a41f2dcbc22ec616
|
||||
modified: 1737618683836
|
||||
created: 1736745679348
|
||||
name: base with vault
|
||||
data:
|
||||
vault: hello
|
||||
dataPropertyOrder:
|
||||
"&":
|
||||
- vault
|
||||
color: null
|
||||
isPrivate: false
|
||||
metaSortKey: 1736745679348
|
||||
environmentType: kv
|
||||
kvPairData:
|
||||
- id: envPair_4bcd80eeb9c544c8a5cca0a1a6a85ffc
|
||||
name: vault
|
||||
value: hello
|
||||
type: str
|
||||
enabled: true
|
||||
_type: environment
|
||||
- _id: env_fce7e052bb99440a9019a162afea7f85
|
||||
parentId: env_40681941450149a4a41f2dcbc22ec616
|
||||
modified: 1737617847199
|
||||
created: 1736745692249
|
||||
name: legacy vault value array
|
||||
data:
|
||||
vault:
|
||||
- vault_array_a
|
||||
- vault_array_b
|
||||
dataPropertyOrder:
|
||||
"&":
|
||||
- vault
|
||||
color: null
|
||||
isPrivate: false
|
||||
metaSortKey: 1736745679398
|
||||
environmentType: json
|
||||
kvPairData: []
|
||||
_type: environment
|
||||
- _id: env_9214888ae2dc497e87a7f8f8edaf19f2
|
||||
parentId: env_40681941450149a4a41f2dcbc22ec616
|
||||
modified: 1737617875350
|
||||
created: 1737617352406
|
||||
name: legacy vault value object
|
||||
data:
|
||||
vault:
|
||||
v1: secv1
|
||||
v2: secv2
|
||||
dataPropertyOrder:
|
||||
"&":
|
||||
- vault
|
||||
"&~|vault":
|
||||
- v1
|
||||
- v2
|
||||
color: null
|
||||
isPrivate: false
|
||||
metaSortKey: 1736881902959
|
||||
environmentType: json
|
||||
kvPairData: []
|
||||
_type: environment
|
||||
@@ -0,0 +1,76 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ContentType } from '../../enums/content-type';
|
||||
import { HttpMethod } from '../../enums/http-method';
|
||||
import { ProjectType } from '../../enums/project-types';
|
||||
import { DEFAULT_TIMEOUT, HTTP_SERVER, test } from '../../misc/fixtures';
|
||||
import { Collection } from '../../models/collection';
|
||||
import { Project } from '../../models/project';
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
|
||||
test('Verify insomnia.test/insomnia.expect report PASS/FAIL results, including a transient variable and insomnia.response accessors', async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(new Project(faker.string.alphanumeric(10), ProjectType.Local));
|
||||
const collection = await workspaceFlow.createCollection(project, new Collection(faker.string.alphanumeric(10)));
|
||||
|
||||
const transientValue = faker.string.alphanumeric(10);
|
||||
const sentValue = faker.string.alphanumeric(10);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: { mimeType: ContentType.JSON, text: `{"sent": "${sentValue}"}` },
|
||||
afterResponseScript: `
|
||||
insomnia.variables.set('transientVar', '${transientValue}');
|
||||
insomnia.test('transient var', () => {
|
||||
insomnia.expect(insomnia.variables.get('transientVar')).to.equal('${transientValue}');
|
||||
});
|
||||
insomnia.test('happyTestInFunc', () => {
|
||||
insomnia.expect(200).to.equal(200);
|
||||
});
|
||||
insomnia.test('response accessors', () => {
|
||||
insomnia.expect(insomnia.response.code).to.equal(200);
|
||||
insomnia.expect(insomnia.response.status).to.equal('OK');
|
||||
insomnia.expect(insomnia.response.json().json.sent).to.equal('${sentValue}');
|
||||
insomnia.expect(insomnia.response.text()).to.include('${sentValue}');
|
||||
insomnia.expect(insomnia.response.headers.get('Content-Type')).to.include('application/json');
|
||||
insomnia.expect(insomnia.response.responseTime).to.be.a('number');
|
||||
insomnia.expect(insomnia.response.size().body).to.be.above(0);
|
||||
});
|
||||
insomnia.test('response assertions', () => {
|
||||
insomnia.response.to.have.status(200);
|
||||
insomnia.response.to.have.header('Content-Type');
|
||||
insomnia.response.to.have.jsonBody('data', '{"sent": "${sentValue}"}');
|
||||
});
|
||||
insomnia.test('unhappy tests', () => {
|
||||
insomnia.expect(199).to.equal(200);
|
||||
});
|
||||
`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
await expect
|
||||
.poll(() => responseView.tests?.(), { timeout: DEFAULT_TIMEOUT })
|
||||
.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ name: 'transient var', status: 'PASS' }),
|
||||
expect.objectContaining({ name: 'happyTestInFunc', status: 'PASS' }),
|
||||
expect.objectContaining({ name: 'response accessors', status: 'PASS' }),
|
||||
expect.objectContaining({
|
||||
name: 'response assertions',
|
||||
status: 'PASS',
|
||||
}),
|
||||
expect.objectContaining({
|
||||
name: 'unhappy tests',
|
||||
status: 'FAIL',
|
||||
error: expect.stringContaining('AssertionError: expected 199 to equal 200'),
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,226 @@
|
||||
import path from "node:path";
|
||||
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ContentType } from "../../enums/content-type";
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
const uploadFilePath = path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"..",
|
||||
"misc",
|
||||
"fixtures",
|
||||
"upload-sample.txt",
|
||||
);
|
||||
|
||||
test("Send HTTP Request with x-www-form-urlencoded Body", async ({ user }) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const title = faker.string.alphanumeric(8);
|
||||
const userId = faker.string.numeric(3);
|
||||
const request = {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: {
|
||||
mimeType: ContentType.Form,
|
||||
params: [
|
||||
{ name: "title", value: title },
|
||||
{ name: "userId", value: userId },
|
||||
{ name: "excluded", value: "should-not-be-sent", disabled: true },
|
||||
],
|
||||
},
|
||||
} satisfies HttpRequest;
|
||||
|
||||
const persisted = await httpRequestFlow.create(collection, request);
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
const raw = (responseView.body as { data: string }).data;
|
||||
|
||||
expect(persisted.body?.mimeType).toBe(ContentType.Form);
|
||||
expect(persisted.body?.params).toMatchObject([
|
||||
{ name: "title", value: title },
|
||||
{ name: "userId", value: userId },
|
||||
{ name: "excluded", disabled: true },
|
||||
]);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(Object.fromEntries(new URLSearchParams(raw))).toEqual({
|
||||
title,
|
||||
userId,
|
||||
});
|
||||
expect(responseView.body).toMatchObject({
|
||||
headers: expect.objectContaining({
|
||||
"content-type": expect.stringContaining(ContentType.Form),
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
test("Send HTTP Request with JSON Body", async ({ user }) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const payload = { title: faker.string.alphanumeric(8), userId: 1 };
|
||||
const request = {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: { mimeType: ContentType.JSON, text: JSON.stringify(payload) },
|
||||
} satisfies HttpRequest;
|
||||
|
||||
await httpRequestFlow.create(collection, request);
|
||||
const persisted = await httpRequestFlow.get(request.name);
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(persisted).toMatchObject(request);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
json: payload,
|
||||
headers: expect.objectContaining({
|
||||
"content-type": expect.stringContaining(ContentType.JSON),
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
test("Send HTTP Request with XML Body", async ({ user }) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const title = faker.string.alphanumeric(8);
|
||||
const xml = `<note><title>${title}</title></note>`;
|
||||
const request = {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: { mimeType: ContentType.XML, text: xml },
|
||||
} satisfies HttpRequest;
|
||||
|
||||
await httpRequestFlow.create(collection, request);
|
||||
const persisted = await httpRequestFlow.get(request.name);
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(persisted).toMatchObject(request);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
data: xml,
|
||||
headers: expect.objectContaining({
|
||||
"content-type": expect.stringContaining(ContentType.XML),
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
test("Send HTTP Request with No Body explicitly selected", async ({ user }) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const request = {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: { mimeType: ContentType.NoBody },
|
||||
} satisfies HttpRequest;
|
||||
|
||||
await httpRequestFlow.create(collection, request);
|
||||
const persisted = await httpRequestFlow.get(request.name);
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(persisted).toMatchObject({
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
body: undefined,
|
||||
});
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
data: "",
|
||||
json: null,
|
||||
});
|
||||
});
|
||||
|
||||
test("Send HTTP Request with multipart/form-data Body including a file field", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow, preferencesFlow } = user.flowManager;
|
||||
|
||||
// Insomnia only reads files from allow-listed directories (Preferences -> General -> Security).
|
||||
await preferencesFlow.set({ dataFolders: [path.dirname(uploadFilePath)] });
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const title = faker.string.alphanumeric(8);
|
||||
const request = {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: {
|
||||
mimeType: ContentType.Multipart,
|
||||
params: [
|
||||
{ name: "title", value: title },
|
||||
{ name: "upload", fileName: uploadFilePath },
|
||||
],
|
||||
},
|
||||
} satisfies HttpRequest;
|
||||
|
||||
await httpRequestFlow.create(collection, request);
|
||||
const persisted = await httpRequestFlow.get(request.name);
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
const raw = (responseView.body as { data: string }).data;
|
||||
|
||||
expect(persisted?.body?.mimeType).toBe(ContentType.Multipart);
|
||||
expect(persisted?.body?.params?.[0]).toMatchObject({
|
||||
name: "title",
|
||||
value: title,
|
||||
});
|
||||
expect(persisted?.body?.params?.[1]?.name).toBe("upload");
|
||||
expect(persisted?.body?.params?.[1]?.fileName).toContain("upload-sample.txt");
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(raw).toContain('name="title"');
|
||||
expect(raw).toContain(title);
|
||||
expect(raw).toContain('name="upload"; filename="upload-sample.txt"');
|
||||
expect(raw).toContain("insomnia-e2e-upload-fixture");
|
||||
expect(responseView.body).toMatchObject({
|
||||
headers: expect.objectContaining({
|
||||
"content-type": expect.stringContaining(ContentType.Multipart),
|
||||
}),
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { RequestState } from "../../enums/request-state";
|
||||
import { DEFAULT_TIMEOUT, HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify Cancelling an In-Flight HTTP Request Shows a Cancellation Message and a Later Request Still Succeeds", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
const { httpRequestPage, responsePage } = user.pageManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const slowRequest = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post`,
|
||||
headers: [{ name: "x-reply-delay-ms", value: "10000" }],
|
||||
});
|
||||
const laterRequest = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post`,
|
||||
});
|
||||
|
||||
await httpRequestFlow.get(slowRequest.name);
|
||||
await httpRequestPage.send();
|
||||
await expect
|
||||
.poll(() => responsePage.getRequestState(), { timeout: DEFAULT_TIMEOUT })
|
||||
.toBe(RequestState.Sending);
|
||||
await responsePage.cancelRequest();
|
||||
await expect
|
||||
.poll(() => responsePage.hasMessage("Request was cancelled"), {
|
||||
timeout: DEFAULT_TIMEOUT,
|
||||
})
|
||||
.toBe(true);
|
||||
const requestStateAfterCancel = await responsePage.getRequestState();
|
||||
const cancelledResponse = await responsePage.get();
|
||||
|
||||
const laterResponse = await httpRequestFlow.send(laterRequest);
|
||||
|
||||
expect(requestStateAfterCancel).toBe(RequestState.Idle);
|
||||
expect(cancelledResponse.statusCode).toBeUndefined();
|
||||
expect(laterResponse.statusCode).toBe(200);
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ContentType } from "../../enums/content-type";
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
const bodyJsonPathFilter = "b64::JC5kYXRh::46b";
|
||||
|
||||
test("Verify A Response Tag Chain Resolves Through Multiple Requests", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const first = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: { mimeType: ContentType.Plain, text: "first" },
|
||||
});
|
||||
const second = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: {
|
||||
mimeType: ContentType.Plain,
|
||||
text: `{% response 'body', '${first.id}', '${bodyJsonPathFilter}', 'always', 60 %} and second`,
|
||||
},
|
||||
});
|
||||
const third = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: {
|
||||
mimeType: ContentType.Plain,
|
||||
text: `{% response 'body', '${second.id}', '${bodyJsonPathFilter}', 'always', 60 %} and third`,
|
||||
},
|
||||
});
|
||||
|
||||
const responseView = await httpRequestFlow.send(third);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({ data: "first and second and third" });
|
||||
});
|
||||
@@ -0,0 +1,53 @@
|
||||
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { certPath } from "../../misc/certs";
|
||||
import { DEFAULT_TIMEOUT, HTTP_SERVER_CUSTOM_CA_HTTPS, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER_CUSTOM_CA_HTTPS}/post`;
|
||||
|
||||
test("Verify Custom CA Root Certificate Establishes Trust For HTTPS Request", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow, certificatesFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const requestBeforeCa = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
});
|
||||
const responseBeforeCa = await httpRequestFlow.send(requestBeforeCa);
|
||||
expect(responseBeforeCa.statusCode).toBeUndefined();
|
||||
await expect
|
||||
.poll(() => responseBeforeCa.console?.(), { timeout: DEFAULT_TIMEOUT })
|
||||
.toMatch(/unable to get local issuer certificate/i);
|
||||
|
||||
await certificatesFlow.setCaCertificate(
|
||||
collection,
|
||||
certPath("mtls-ca.pem"),
|
||||
);
|
||||
|
||||
const requestAfterCa = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
});
|
||||
const responseAfterCa = await httpRequestFlow.send(requestAfterCa);
|
||||
expect(responseAfterCa.statusCode).toBe(200);
|
||||
expect(responseAfterCa.body).toMatchObject({
|
||||
headers: expect.objectContaining({ host: "localhost:4062" }),
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,53 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { DEFAULT_TIMEOUT, HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Folder } from "../../models/folder";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
|
||||
test("Verify a folder-level script wrapping insomnia.variables.replaceIn resolves synchronously for a downstream request consuming it without await", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { folderFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
const folder = await folderFlow.create(
|
||||
collection,
|
||||
new Folder(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
await folderFlow.setScripts(folder, {
|
||||
preRequest: `
|
||||
insomnia.globals.set('firstname', insomnia.variables.replaceIn('{{ $randomFirstName }}'));
|
||||
`,
|
||||
});
|
||||
|
||||
const request = await httpRequestFlow.create(folder, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
preRequestScript: `
|
||||
const firstname = insomnia.globals.get('firstname');
|
||||
console.log(typeof firstname, firstname);
|
||||
`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
await expect
|
||||
.poll(() => responseView.console?.(), { timeout: DEFAULT_TIMEOUT })
|
||||
.toMatch(/log: string \S+/);
|
||||
const consoleText = await responseView.console?.();
|
||||
expect(consoleText).not.toContain("Promise");
|
||||
expect(consoleText).not.toContain("undefined");
|
||||
});
|
||||
@@ -0,0 +1,50 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/get`;
|
||||
|
||||
test("Verify switching the Generate Code dialog's target language and client library regenerates the snippet", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url,
|
||||
});
|
||||
|
||||
const shellCurlCode = await workspaceFlow.generateCode(request);
|
||||
const pythonCode = await workspaceFlow.generateCode(request, {
|
||||
target: "Python",
|
||||
client: "http.client",
|
||||
});
|
||||
const nodeAxiosCode = await workspaceFlow.generateCode(request, {
|
||||
target: "Node.js",
|
||||
client: "Axios",
|
||||
});
|
||||
const nodeFetchCode = await workspaceFlow.generateCode(request, {
|
||||
target: "Node.js",
|
||||
client: "Fetch",
|
||||
});
|
||||
|
||||
expect(shellCurlCode).toContain("curl");
|
||||
expect(pythonCode).toContain("import http.client");
|
||||
expect(nodeAxiosCode).toContain("require('axios')");
|
||||
expect(nodeAxiosCode).toContain("axios.request");
|
||||
expect(nodeFetchCode).toContain("require('node-fetch')");
|
||||
expect(nodeFetchCode).not.toContain("axios");
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
|
||||
test("Verify Generate Code Produces A Matching cURL Snippet", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url,
|
||||
});
|
||||
|
||||
const code = await workspaceFlow.generateCode(request);
|
||||
|
||||
expect(code).toContain("curl");
|
||||
expect(code).toContain("--request GET");
|
||||
expect(code).toContain(url);
|
||||
});
|
||||
@@ -0,0 +1,52 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { DEFAULT_TIMEOUT, HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify Import from URL Moves Query String Into Params and Preserves It on Send", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
const { httpRequestPage } = user.pageManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const paramName1 = faker.string.alphanumeric(8);
|
||||
const paramValue1 = faker.string.alphanumeric(8);
|
||||
const paramName2 = faker.string.alphanumeric(8);
|
||||
const paramValue2 = faker.string.alphanumeric(8);
|
||||
const baseUrl = `${HTTP_SERVER}/get`;
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${baseUrl}?${paramName1}=${paramValue1}&${paramName2}=${paramValue2}`,
|
||||
});
|
||||
await httpRequestPage.importParamsFromUrl();
|
||||
const updatedUrl = await httpRequestPage.getUrl();
|
||||
const updatedParams = await httpRequestPage.getParams();
|
||||
const responseView = await httpRequestFlow.send(request!);
|
||||
|
||||
expect(updatedUrl).toBe(baseUrl);
|
||||
expect(updatedParams).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ name: paramName1, value: paramValue1 }),
|
||||
expect.objectContaining({ name: paramName2, value: paramValue2 }),
|
||||
]),
|
||||
);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
await expect
|
||||
.poll(() => responseView.console?.(), { timeout: DEFAULT_TIMEOUT })
|
||||
.toContain(
|
||||
`Preparing request to ${baseUrl}?${paramName1}=${paramValue1}&${paramName2}=${paramValue2}`,
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ContentType } from "../../enums/content-type";
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = "http://[::1]:4060/post";
|
||||
|
||||
test("Verify HTTP request succeeds against a local IPv6 address", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const bodyText = faker.string.alphanumeric(10);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: url,
|
||||
body: { mimeType: ContentType.Plain, text: bodyText },
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request!);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.statusMessage).toBe("OK");
|
||||
expect(responseView.body).toMatchObject({ data: bodyText });
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify Trailing Blank Row In Headers And Params Is Not Persisted Until Typed Into", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
const { httpRequestPage } = user.pageManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${HTTP_SERVER}/get`,
|
||||
});
|
||||
|
||||
const headersBefore = await httpRequestPage.getHeaders();
|
||||
const paramsBefore = await httpRequestPage.getParams();
|
||||
const headerName = faker.string.alphanumeric(8);
|
||||
const headerValue = faker.string.alphanumeric(8);
|
||||
const paramName = faker.string.alphanumeric(8);
|
||||
const paramValue = faker.string.alphanumeric(8);
|
||||
await httpRequestPage.setHeaders([{ name: headerName, value: headerValue }]);
|
||||
await httpRequestPage.setParams([{ name: paramName, value: paramValue }]);
|
||||
const headersAfter = await httpRequestPage.getHeaders();
|
||||
const paramsAfter = await httpRequestPage.getParams();
|
||||
|
||||
const isBlank = (pair: { name: string; value: string }) =>
|
||||
pair.name === "" && pair.value === "";
|
||||
|
||||
expect(request).toBeDefined();
|
||||
expect(headersBefore.some(isBlank)).toBe(false);
|
||||
expect(paramsBefore.some(isBlank)).toBe(false);
|
||||
expect(headersAfter.some(isBlank)).toBe(false);
|
||||
expect(paramsAfter.some(isBlank)).toBe(false);
|
||||
expect(headersAfter).toHaveLength(headersBefore.length + 1);
|
||||
expect(paramsAfter).toHaveLength(paramsBefore.length + 1);
|
||||
expect(headersAfter).toEqual(
|
||||
expect.arrayContaining([
|
||||
{ name: headerName, value: headerValue, disabled: false },
|
||||
]),
|
||||
);
|
||||
expect(paramsAfter).toEqual(
|
||||
expect.arrayContaining([
|
||||
{ name: paramName, value: paramValue, disabled: false },
|
||||
]),
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,106 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ContentType } from "../../enums/content-type";
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { EnvironmentKvPairDataType } from "../../models/environment";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
|
||||
test("Verify LiquidJS control flow tags render correctly", async ({ user }) => {
|
||||
const { environmentFlow, httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const envValue = faker.string.alphanumeric(8);
|
||||
const environment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: "Base Environment",
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: "envVar",
|
||||
value: envValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
await environmentFlow.link(collection, environment);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: {
|
||||
mimeType: ContentType.Plain,
|
||||
text: `{{ envVar }}-{% assign x = 5 %}{% if x > 3 %}big{% else %}small{% endif %}-{% for i in (1..3) %}{{ i }}{% endfor %}-{% unless x == 5 %}no{% else %}yes{% endunless %}`,
|
||||
},
|
||||
} satisfies HttpRequest);
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
data: `${envValue}-big-123-yes`,
|
||||
});
|
||||
});
|
||||
|
||||
test("Verify LiquidJS include/render/layout tags are blocked", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const includeRequest = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: { mimeType: ContentType.Plain, text: `{% include 'foo' %}` },
|
||||
} satisfies HttpRequest);
|
||||
const renderRequest = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: { mimeType: ContentType.Plain, text: `{% render 'foo' %}` },
|
||||
} satisfies HttpRequest);
|
||||
const layoutRequest = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: { mimeType: ContentType.Plain, text: `{% layout 'foo' %}` },
|
||||
} satisfies HttpRequest);
|
||||
|
||||
const blockedTagPattern = /include.*render.*layout.*disabled/is;
|
||||
|
||||
await expect(httpRequestFlow.send(includeRequest)).rejects.toThrow(
|
||||
blockedTagPattern,
|
||||
);
|
||||
await workspaceFlow.closeDialog();
|
||||
|
||||
await expect(httpRequestFlow.send(renderRequest)).rejects.toThrow(
|
||||
blockedTagPattern,
|
||||
);
|
||||
await workspaceFlow.closeDialog();
|
||||
|
||||
await expect(httpRequestFlow.send(layoutRequest)).rejects.toThrow(
|
||||
blockedTagPattern,
|
||||
);
|
||||
await workspaceFlow.closeDialog();
|
||||
});
|
||||
@@ -0,0 +1,78 @@
|
||||
import path from "node:path";
|
||||
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { certPath } from "../../misc/certs";
|
||||
import { DEFAULT_TIMEOUT, HTTP_SERVER_MTLS, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER_MTLS}/post`;
|
||||
|
||||
test("Verify Client Certificate Toggle Controls mTLS Enforcement For HTTP Request", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow, preferencesFlow, certificatesFlow } =
|
||||
user.flowManager;
|
||||
|
||||
await preferencesFlow.set({
|
||||
validateSSL: false,
|
||||
dataFolders: [path.join(__dirname, "../../misc/fixtures")],
|
||||
});
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const requestBeforeCert = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
});
|
||||
const responseBeforeCert = await httpRequestFlow.send(requestBeforeCert);
|
||||
expect(responseBeforeCert.statusCode).toBeUndefined();
|
||||
await expect
|
||||
.poll(() => responseBeforeCert.console?.(), { timeout: DEFAULT_TIMEOUT })
|
||||
.toMatch(/certificate required/i);
|
||||
|
||||
await certificatesFlow.addClientCertificate(collection, {
|
||||
host: "localhost",
|
||||
cert: certPath("mtls-client-cert.pem"),
|
||||
key: certPath("mtls-client-key.pem"),
|
||||
});
|
||||
|
||||
const requestWithCert = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
});
|
||||
const responseWithCert = await httpRequestFlow.send(requestWithCert);
|
||||
expect(responseWithCert.statusCode).toBe(200);
|
||||
expect(responseWithCert.body).toMatchObject({
|
||||
headers: expect.objectContaining({ host: "localhost:4063" }),
|
||||
});
|
||||
|
||||
await certificatesFlow.setClientCertificateEnabled(
|
||||
collection,
|
||||
"localhost",
|
||||
false,
|
||||
);
|
||||
|
||||
const requestAfterDisable = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
});
|
||||
const responseAfterDisable = await httpRequestFlow.send(requestAfterDisable);
|
||||
expect(responseAfterDisable.statusCode).toBeUndefined();
|
||||
await expect
|
||||
.poll(() => responseAfterDisable.console?.(), { timeout: DEFAULT_TIMEOUT })
|
||||
.toMatch(/certificate required/i);
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import type { AuthTypeOAuth1 } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify OAuth 1.0 auth fields persist and sign the sent request", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const authentication: AuthTypeOAuth1 = {
|
||||
type: "oauth1",
|
||||
consumerKey: faker.string.alphanumeric(10),
|
||||
consumerSecret: faker.string.alphanumeric(10),
|
||||
tokenKey: faker.string.alphanumeric(10),
|
||||
tokenSecret: faker.string.alphanumeric(10),
|
||||
signatureMethod: "HMAC-SHA256",
|
||||
callback: "https://example.com/callback",
|
||||
version: "1.0",
|
||||
realm: faker.string.alphanumeric(8),
|
||||
};
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post`,
|
||||
authentication: authentication,
|
||||
});
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
const authHeader = (responseView.body as { headers: Record<string, string> })
|
||||
.headers.authorization;
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(authHeader).toContain("OAuth ");
|
||||
expect(authHeader).toContain(
|
||||
`oauth_consumer_key="${authentication.consumerKey}"`,
|
||||
);
|
||||
expect(authHeader).toContain(`oauth_token="${authentication.tokenKey}"`);
|
||||
expect(authHeader).toContain(
|
||||
`oauth_signature_method="${authentication.signatureMethod}"`,
|
||||
);
|
||||
expect(authHeader).toContain(`oauth_version="${authentication.version}"`);
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET, OAUTH2_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import type { AuthTypeOAuth2 } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
for (const pkceMethod of ["S256", "plain"] as const) {
|
||||
test(`Verify Authorization Code grant with PKCE (${pkceMethod}) is verified server-side and authorizes the sent request`, async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const authentication: AuthTypeOAuth2 = {
|
||||
type: "oauth2",
|
||||
grantType: "authorization_code",
|
||||
authorizationUrl: `${OAUTH2_SERVER}/authorize`,
|
||||
accessTokenUrl: `${OAUTH2_SERVER}/token`,
|
||||
clientId: OAUTH2_CLIENT_ID,
|
||||
clientSecret: OAUTH2_CLIENT_SECRET,
|
||||
redirectUrl: `${OAUTH2_SERVER}/health`,
|
||||
usePkce: true,
|
||||
pkceMethod,
|
||||
};
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${OAUTH2_SERVER}/resource`,
|
||||
authentication: authentication,
|
||||
});
|
||||
|
||||
const tokens = await httpRequestFlow.fetchOAuth2Tokens(request);
|
||||
|
||||
const lastTokenRequest = await (
|
||||
await fetch(
|
||||
`${OAUTH2_SERVER}/_debug/last-token-request?access_token=${encodeURIComponent(tokens.accessToken)}`,
|
||||
)
|
||||
).json();
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
const body = responseView.body as { authorization?: string };
|
||||
|
||||
expect(tokens.accessToken).not.toBe("");
|
||||
expect(lastTokenRequest.grantType).toBe("authorization_code");
|
||||
expect(lastTokenRequest.pkceUsed).toBe(true);
|
||||
expect(lastTokenRequest.pkceMethod).toBe(pkceMethod);
|
||||
expect(lastTokenRequest.pkceVerified).toBe(true);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(body.authorization).toBe(`Bearer ${tokens.accessToken}`);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET, OAUTH2_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import type { AuthTypeOAuth2 } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify Authorization Code grant fetches tokens via a popup and authorizes the sent request", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const authentication: AuthTypeOAuth2 = {
|
||||
type: "oauth2",
|
||||
grantType: "authorization_code",
|
||||
authorizationUrl: `${OAUTH2_SERVER}/authorize`,
|
||||
accessTokenUrl: `${OAUTH2_SERVER}/token`,
|
||||
clientId: OAUTH2_CLIENT_ID,
|
||||
clientSecret: OAUTH2_CLIENT_SECRET,
|
||||
redirectUrl: `${OAUTH2_SERVER}/health`,
|
||||
};
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${OAUTH2_SERVER}/resource`,
|
||||
authentication: authentication,
|
||||
});
|
||||
|
||||
const tokens = await httpRequestFlow.fetchOAuth2Tokens(request);
|
||||
|
||||
const lastTokenRequest = await (
|
||||
await fetch(
|
||||
`${OAUTH2_SERVER}/_debug/last-token-request?access_token=${encodeURIComponent(tokens.accessToken)}`,
|
||||
)
|
||||
).json();
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
const body = responseView.body as { authorization?: string };
|
||||
|
||||
expect(tokens.accessToken).not.toBe("");
|
||||
expect(tokens.refreshToken).not.toBe("");
|
||||
expect(tokens.identityToken).not.toBe("");
|
||||
expect(lastTokenRequest.grantType).toBe("authorization_code");
|
||||
expect(lastTokenRequest.pkceUsed).toBe(false);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(body.authorization).toBe(`Bearer ${tokens.accessToken}`);
|
||||
});
|
||||
@@ -0,0 +1,57 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET, OAUTH2_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import type { AuthTypeOAuth2 } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify Client Credentials grant fetches tokens with no popup and authorizes the sent request", async ({
|
||||
user,
|
||||
insomnia,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const authentication: AuthTypeOAuth2 = {
|
||||
type: "oauth2",
|
||||
grantType: "client_credentials",
|
||||
accessTokenUrl: `${OAUTH2_SERVER}/token`,
|
||||
clientId: OAUTH2_CLIENT_ID,
|
||||
clientSecret: OAUTH2_CLIENT_SECRET,
|
||||
};
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${OAUTH2_SERVER}/resource`,
|
||||
authentication: authentication,
|
||||
});
|
||||
|
||||
const windowsBeforeFetch = insomnia.windows().length;
|
||||
const tokens = await httpRequestFlow.fetchOAuth2Tokens(request);
|
||||
const windowsAfterFetch = insomnia.windows().length;
|
||||
|
||||
const lastTokenRequest = await (
|
||||
await fetch(
|
||||
`${OAUTH2_SERVER}/_debug/last-token-request?access_token=${encodeURIComponent(tokens.accessToken)}`,
|
||||
)
|
||||
).json();
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
const body = responseView.body as { authorization?: string };
|
||||
|
||||
expect(tokens.accessToken).not.toBe("");
|
||||
expect(windowsAfterFetch).toBe(windowsBeforeFetch);
|
||||
expect(lastTokenRequest.grantType).toBe("client_credentials");
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(body.authorization).toBe(`Bearer ${tokens.accessToken}`);
|
||||
});
|
||||
@@ -0,0 +1,53 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { AuthType } from "../../enums/auth-type";
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET, OAUTH2_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Folder } from "../../models/folder";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify a request set to Inherit from parent picks up its folder's OAuth 2.0 authentication", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, folderFlow, httpRequestFlow } = user.flowManager;
|
||||
const { httpRequestPage, folderPage } = user.pageManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
const folder = await folderFlow.create(
|
||||
collection,
|
||||
new Folder(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
await folderFlow.open(folder);
|
||||
await folderPage.auth.setOAuth2Fields({
|
||||
type: "oauth2",
|
||||
grantType: "client_credentials",
|
||||
accessTokenUrl: `${OAUTH2_SERVER}/token`,
|
||||
clientId: OAUTH2_CLIENT_ID,
|
||||
clientSecret: OAUTH2_CLIENT_SECRET,
|
||||
});
|
||||
const folderTokens = await folderFlow.fetchOAuth2Tokens(folder);
|
||||
|
||||
const request = await httpRequestFlow.create(folder, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${OAUTH2_SERVER}/resource`,
|
||||
});
|
||||
await httpRequestPage.auth.setAuthType(AuthType.Inherit);
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
const body = responseView.body as { authorization?: string };
|
||||
|
||||
expect(folderTokens.accessToken).not.toBe("");
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(body.authorization).toBe(`Bearer ${folderTokens.accessToken}`);
|
||||
});
|
||||
@@ -0,0 +1,85 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { OAUTH2_CLIENT_ID, OAUTH2_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import type { AuthTypeOAuth2 } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify Implicit grant with response type ID Token fetches only an identity token", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const authentication: AuthTypeOAuth2 = {
|
||||
type: "oauth2",
|
||||
grantType: "implicit",
|
||||
authorizationUrl: `${OAUTH2_SERVER}/authorize`,
|
||||
clientId: OAUTH2_CLIENT_ID,
|
||||
redirectUrl: `${OAUTH2_SERVER}/health`,
|
||||
responseType: "id_token",
|
||||
};
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${OAUTH2_SERVER}/resource`,
|
||||
authentication: authentication,
|
||||
});
|
||||
|
||||
const tokens = await httpRequestFlow.fetchOAuth2Tokens(request);
|
||||
|
||||
// With no separate access_token in the fragment, the app displays the
|
||||
// identity token in the Access Token field too, rather than leaving it
|
||||
// blank.
|
||||
expect(tokens.identityToken).not.toBe("");
|
||||
expect(tokens.accessToken).toBe(tokens.identityToken);
|
||||
});
|
||||
|
||||
test("Verify Implicit grant with response type ID and Access Token authorizes the sent request", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const authentication: AuthTypeOAuth2 = {
|
||||
type: "oauth2",
|
||||
grantType: "implicit",
|
||||
authorizationUrl: `${OAUTH2_SERVER}/authorize`,
|
||||
clientId: OAUTH2_CLIENT_ID,
|
||||
redirectUrl: `${OAUTH2_SERVER}/health`,
|
||||
responseType: "id_token token",
|
||||
};
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${OAUTH2_SERVER}/resource`,
|
||||
authentication: authentication,
|
||||
});
|
||||
|
||||
const tokens = await httpRequestFlow.fetchOAuth2Tokens(request);
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
const body = responseView.body as { authorization?: string };
|
||||
|
||||
expect(tokens.identityToken).not.toBe("");
|
||||
expect(tokens.accessToken).not.toBe("");
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(body.authorization).toBe(`Bearer ${tokens.accessToken}`);
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET, OAUTH2_PASSWORD, OAUTH2_SERVER, OAUTH2_USERNAME, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import type { AuthTypeOAuth2 } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify Resource Owner Password Credentials grant fetches tokens with no popup and authorizes the sent request", async ({
|
||||
user,
|
||||
insomnia,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const authentication: AuthTypeOAuth2 = {
|
||||
type: "oauth2",
|
||||
grantType: "password",
|
||||
accessTokenUrl: `${OAUTH2_SERVER}/token`,
|
||||
clientId: OAUTH2_CLIENT_ID,
|
||||
clientSecret: OAUTH2_CLIENT_SECRET,
|
||||
username: OAUTH2_USERNAME,
|
||||
password: OAUTH2_PASSWORD,
|
||||
};
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${OAUTH2_SERVER}/resource`,
|
||||
authentication: authentication,
|
||||
});
|
||||
|
||||
const windowsBeforeFetch = insomnia.windows().length;
|
||||
const tokens = await httpRequestFlow.fetchOAuth2Tokens(request);
|
||||
const windowsAfterFetch = insomnia.windows().length;
|
||||
|
||||
const lastTokenRequest = await (
|
||||
await fetch(
|
||||
`${OAUTH2_SERVER}/_debug/last-token-request?access_token=${encodeURIComponent(tokens.accessToken)}`,
|
||||
)
|
||||
).json();
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
const body = responseView.body as { authorization?: string };
|
||||
|
||||
expect(tokens.accessToken).not.toBe("");
|
||||
expect(tokens.refreshToken).not.toBe("");
|
||||
expect(windowsAfterFetch).toBe(windowsBeforeFetch);
|
||||
expect(lastTokenRequest.grantType).toBe("password");
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(body.authorization).toBe(`Bearer ${tokens.accessToken}`);
|
||||
});
|
||||
@@ -0,0 +1,97 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET, OAUTH2_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import type { AuthTypeOAuth2 } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify refreshing an existing OAuth 2.0 token issues a new access token without reopening the authorization window", async ({
|
||||
user,
|
||||
insomnia,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const authentication: AuthTypeOAuth2 = {
|
||||
type: "oauth2",
|
||||
grantType: "authorization_code",
|
||||
authorizationUrl: `${OAUTH2_SERVER}/authorize`,
|
||||
accessTokenUrl: `${OAUTH2_SERVER}/token`,
|
||||
clientId: OAUTH2_CLIENT_ID,
|
||||
clientSecret: OAUTH2_CLIENT_SECRET,
|
||||
redirectUrl: `${OAUTH2_SERVER}/health`,
|
||||
};
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${OAUTH2_SERVER}/resource`,
|
||||
authentication: authentication,
|
||||
});
|
||||
|
||||
const tokensAfterFetch = await httpRequestFlow.fetchOAuth2Tokens(request);
|
||||
|
||||
const windowsBeforeRefresh = insomnia.windows().length;
|
||||
const tokensAfterRefresh = await httpRequestFlow.fetchOAuth2Tokens(request);
|
||||
const windowsAfterRefresh = insomnia.windows().length;
|
||||
|
||||
const lastTokenRequest = await (
|
||||
await fetch(
|
||||
`${OAUTH2_SERVER}/_debug/last-token-request?access_token=${encodeURIComponent(tokensAfterRefresh.accessToken)}`,
|
||||
)
|
||||
).json();
|
||||
|
||||
expect(tokensAfterFetch.accessToken).not.toBe("");
|
||||
expect(windowsAfterRefresh).toBe(windowsBeforeRefresh);
|
||||
expect(lastTokenRequest.grantType).toBe("refresh_token");
|
||||
expect(tokensAfterRefresh.refreshToken).toBe(tokensAfterFetch.refreshToken);
|
||||
expect(tokensAfterRefresh.accessToken).not.toBe(tokensAfterFetch.accessToken);
|
||||
});
|
||||
|
||||
test("Verify clearing OAuth 2.0 tokens wipes the stored Refresh/Identity/Access Token fields", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
const { httpRequestPage } = user.pageManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const authentication: AuthTypeOAuth2 = {
|
||||
type: "oauth2",
|
||||
grantType: "client_credentials",
|
||||
accessTokenUrl: `${OAUTH2_SERVER}/token`,
|
||||
clientId: OAUTH2_CLIENT_ID,
|
||||
clientSecret: OAUTH2_CLIENT_SECRET,
|
||||
};
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${OAUTH2_SERVER}/resource`,
|
||||
authentication: authentication,
|
||||
});
|
||||
|
||||
const tokensAfterFetch = await httpRequestFlow.fetchOAuth2Tokens(request);
|
||||
|
||||
await httpRequestPage.auth.clearOAuth2Tokens();
|
||||
const tokensAfterClear = await httpRequestPage.auth.getOAuth2Tokens();
|
||||
|
||||
expect(tokensAfterFetch.accessToken).not.toBe("");
|
||||
expect(tokensAfterClear.accessToken).toBe("");
|
||||
expect(tokensAfterClear.refreshToken).toBe("");
|
||||
expect(tokensAfterClear.identityToken).toBe("");
|
||||
});
|
||||
@@ -0,0 +1,91 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ContentType } from "../../enums/content-type";
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
|
||||
test("Verify pending async work in a pre-request script (Promise, setTimeout, sendRequest callback/await) is settled before the request is sent, and a synchronous replaceIn call in the same script is unaffected by it", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const syncVariableName = faker.string.alpha(8);
|
||||
const syncVariableValue = faker.string.alphanumeric(10);
|
||||
|
||||
const marker = faker.string.alphanumeric(10);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: {
|
||||
mimeType: ContentType.JSON,
|
||||
text: `{"asyncDoneViaPromise": {{ asyncDoneViaPromise }}, "asyncDoneViaTimeout": {{ asyncDoneViaTimeout }}, "asyncDoneViaCallback": {{ asyncDoneViaCallback }}, "bodyFromAwait": {{ bodyFromAwait }}, "bodyFromCallback": {{ bodyFromCallback }}, "syncReplaceInResult": "{{ syncReplaceInResult }}"}`,
|
||||
},
|
||||
preRequestScript: `
|
||||
insomnia.environment.set('${syncVariableName}', '${syncVariableValue}');
|
||||
const syncReplaceInResult = insomnia.environment.replaceIn('{{ ${syncVariableName} }}');
|
||||
insomnia.environment.set('syncReplaceInResult', syncReplaceInResult);
|
||||
|
||||
new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
insomnia.environment.set('asyncDoneViaPromise', true);
|
||||
resolve();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
insomnia.environment.set('asyncDoneViaTimeout', true);
|
||||
}, 500);
|
||||
|
||||
insomnia.sendRequest({ url: '${url}', method: 'POST' }, (err, resp) => {
|
||||
if (err != null) {
|
||||
throw err;
|
||||
} else {
|
||||
insomnia.environment.set('asyncDoneViaCallback', true);
|
||||
}
|
||||
});
|
||||
|
||||
let respFromCallback;
|
||||
const respFromAwait = await insomnia.sendRequest({
|
||||
url: '${url}',
|
||||
method: 'POST',
|
||||
body: { mode: 'raw', raw: '${marker}' },
|
||||
}, (err, resp) => {
|
||||
if (err != null) {
|
||||
throw err;
|
||||
} else {
|
||||
respFromCallback = resp;
|
||||
}
|
||||
});
|
||||
insomnia.environment.set('bodyFromAwait', respFromAwait.body);
|
||||
insomnia.environment.set('bodyFromCallback', respFromCallback.body);
|
||||
`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
json: {
|
||||
asyncDoneViaPromise: true,
|
||||
asyncDoneViaTimeout: true,
|
||||
asyncDoneViaCallback: true,
|
||||
bodyFromAwait: expect.objectContaining({ data: marker }),
|
||||
bodyFromCallback: expect.objectContaining({ data: marker }),
|
||||
syncReplaceInResult: syncVariableValue,
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from '../../enums/http-method';
|
||||
import { ProjectType } from '../../enums/project-types';
|
||||
import { HTTP_SERVER, test } from '../../misc/fixtures';
|
||||
import { Collection } from '../../models/collection';
|
||||
import { Project } from '../../models/project';
|
||||
|
||||
test('Verify pre-request script manages cookies via insomnia.cookies.jar() and they are sent with the request', async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(new Project(faker.string.alphanumeric(10), ProjectType.Local));
|
||||
const collection = await workspaceFlow.createCollection(project, new Collection(faker.string.alphanumeric(10)));
|
||||
|
||||
const keptName = faker.string.alpha(8);
|
||||
const keptValue = faker.string.alphanumeric(10);
|
||||
const unsetName = faker.string.alpha(9);
|
||||
const objectName = faker.string.alpha(10);
|
||||
const objectValue = faker.string.alphanumeric(10);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${HTTP_SERVER}/cookies`,
|
||||
preRequestScript: `
|
||||
const jar = insomnia.cookies.jar();
|
||||
const call = (fn, ...args) => new Promise((resolve, reject) => fn.call(jar, ...args, (err, res) => err ? reject(err) : resolve(res)));
|
||||
await call(jar.set, '${HTTP_SERVER}', '${keptName}', { key: '${keptName}', value: '${keptValue}', domain: 'localhost' });
|
||||
await call(jar.set, '${HTTP_SERVER}', '${unsetName}', { key: '${unsetName}', value: 'temporary', domain: 'localhost' });
|
||||
await call(jar.set, '${HTTP_SERVER}', '${objectName}', { key: '${objectName}', value: '${objectValue}', domain: 'localhost' });
|
||||
await call(jar.unset, '${HTTP_SERVER}', '${unsetName}');
|
||||
`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toEqual({
|
||||
cookies: { [keptName]: keptValue, [objectName]: objectValue },
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,63 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { DEFAULT_TIMEOUT, HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
|
||||
test("Verify a thrown error in pre-request script surfaces in the response console", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const errorMessage = faker.string.alphanumeric(10);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
preRequestScript: `throw new Error('${errorMessage}');`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
await expect
|
||||
.poll(() => responseView.console?.(), { timeout: DEFAULT_TIMEOUT })
|
||||
.toContain(errorMessage);
|
||||
});
|
||||
|
||||
test("Verify accessing an invalid field in pre-request script surfaces in the response console", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
preRequestScript: `insomnia.INVALID_FIELD.set('', '');`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
await expect
|
||||
.poll(() => responseView.console?.(), { timeout: DEFAULT_TIMEOUT })
|
||||
.toContain("Cannot read properties of undefined (reading 'set')");
|
||||
});
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ContentType } from "../../enums/content-type";
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
|
||||
test("Verify pre-request script overrides base environment values through the environment chain and persists set/get variables", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow, environmentFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const baseEnvironment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
});
|
||||
const subEnvironment = await environmentFlow.createSubEnvironment(baseEnvironment, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
});
|
||||
await environmentFlow.link(collection, subEnvironment);
|
||||
|
||||
const fallbackValue = faker.string.alphanumeric(10);
|
||||
const baseScriptValue = faker.string.alphanumeric(10);
|
||||
const envScriptValue = faker.string.alphanumeric(10);
|
||||
const preDefinedValue = faker.string.alphanumeric(10);
|
||||
const varStr = faker.string.alphanumeric(10);
|
||||
const varNum = faker.number.int({ min: 1, max: 1000 });
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: {
|
||||
mimeType: ContentType.JSON,
|
||||
text: `{"fallbackToBase": "{{ fallbackToBase }}", "scriptValue": "{{ scriptValue }}", "preDefinedValue": "{{ preDefinedValue }}", "varStr": "{{ varStr }}", "varNum": {{ varNum }}, "varBool": {{ varBool }}}`,
|
||||
},
|
||||
preRequestScript: `
|
||||
insomnia.baseEnvironment.set('fallbackToBase', '${fallbackValue}');
|
||||
insomnia.baseEnvironment.set('scriptValue', '${baseScriptValue}');
|
||||
insomnia.environment.set('scriptValue', '${envScriptValue}');
|
||||
insomnia.baseEnvironment.set('preDefinedValue', '${preDefinedValue}');
|
||||
|
||||
insomnia.variables.set('varStr', '${varStr}');
|
||||
insomnia.variables.set('varNum', ${varNum});
|
||||
insomnia.variables.set('varBool', true);
|
||||
insomnia.environment.set('varStr', insomnia.variables.get('varStr'));
|
||||
insomnia.environment.set('varNum', insomnia.variables.get('varNum'));
|
||||
insomnia.environment.set('varBool', insomnia.variables.get('varBool'));
|
||||
`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
json: {
|
||||
fallbackToBase: fallbackValue,
|
||||
scriptValue: envScriptValue,
|
||||
preDefinedValue: preDefinedValue,
|
||||
varStr,
|
||||
varNum,
|
||||
varBool: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ContentType } from "../../enums/content-type";
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
|
||||
test("Verify pre-request script can eval() and require Node built-in modules, external modules, and insomnia-collection classes", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const parsedUrl = new URL(
|
||||
"https://user:pwd@insomnia.com:6666/p1?q1=a&q2=b#hashcontent",
|
||||
);
|
||||
const builtinModules = [
|
||||
"path",
|
||||
"assert",
|
||||
"buffer",
|
||||
"util",
|
||||
"url",
|
||||
"punycode",
|
||||
"querystring",
|
||||
"string_decoder",
|
||||
"stream",
|
||||
"timers",
|
||||
"events",
|
||||
];
|
||||
const externalModules = {
|
||||
atob: "atob",
|
||||
btoa: "btoa",
|
||||
chai: "chai",
|
||||
cheerio: "cheerio",
|
||||
crypto: "crypto-js",
|
||||
csv: "csv-parse/lib/sync",
|
||||
lodash: "lodash",
|
||||
moment: "moment",
|
||||
tv4: "tv4",
|
||||
uuid: "uuid",
|
||||
xml2js: "xml2js",
|
||||
};
|
||||
const externalModuleKeys = Object.keys(externalModules);
|
||||
const propertyId = faker.string.alphanumeric(10);
|
||||
const propertyName = faker.string.alphanumeric(10);
|
||||
const headerKey = faker.string.alphanumeric(10);
|
||||
const headerValue = faker.string.alphanumeric(10);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: {
|
||||
mimeType: ContentType.JSON,
|
||||
text: `{"evalResult": {{ evalResult }}, "hash": "{{ hash }}", "host": "{{ host }}", "hostname": "{{ hostname }}", "origin": "{{ origin }}", "password": "{{ password }}", "pathname": "{{ pathname }}", "port": "{{ port }}", "protocol": "{{ protocol }}", "search": "{{ search }}", "username": "{{ username }}", "searchParam": "{{ searchParam }}", ${builtinModules.map((m) => `"${m}": {{ ${m} }}`).join(", ")}, ${externalModuleKeys.map((k) => `"${k}": {{ ${k} }}`).join(", ")}, "builtInLodash": {{ builtInLodash }}, "uuidNil": "{{ uuidNil }}", "propJson": {{ propJson }}, "headerJson": {{ headerJson }}}`,
|
||||
},
|
||||
preRequestScript: `
|
||||
const evalResult = eval('8+8');
|
||||
insomnia.environment.set('evalResult', evalResult);
|
||||
|
||||
const { URL } = require('url');
|
||||
const parsedUrl = new URL('${parsedUrl.href}');
|
||||
insomnia.environment.set('hash', parsedUrl.hash);
|
||||
insomnia.environment.set('host', parsedUrl.host);
|
||||
insomnia.environment.set('hostname', parsedUrl.hostname);
|
||||
insomnia.environment.set('origin', parsedUrl.origin);
|
||||
insomnia.environment.set('password', parsedUrl.password);
|
||||
insomnia.environment.set('pathname', parsedUrl.pathname);
|
||||
insomnia.environment.set('port', parsedUrl.port);
|
||||
insomnia.environment.set('protocol', parsedUrl.protocol);
|
||||
insomnia.environment.set('search', parsedUrl.search);
|
||||
insomnia.environment.set('username', parsedUrl.username);
|
||||
insomnia.environment.set('searchParam', parsedUrl.searchParams.toString());
|
||||
|
||||
${builtinModules.map((m) => `insomnia.environment.set('${m}', require('${m}') != null);`).join("\n")}
|
||||
|
||||
${externalModuleKeys.map((k) => `insomnia.environment.set('${k}', require('${externalModules[k as keyof typeof externalModules]}') != null);`).join("\n")}
|
||||
insomnia.environment.set('builtInLodash', _ != null);
|
||||
|
||||
const uuid = require('uuid');
|
||||
insomnia.environment.set('uuidNil', uuid.NIL);
|
||||
|
||||
const { Property, Header } = require('insomnia-collection');
|
||||
const prop = new Property('${propertyId}', '${propertyName}');
|
||||
const header = new Header({ key: '${headerKey}', value: '${headerValue}' });
|
||||
insomnia.environment.set('propJson', JSON.stringify(prop.toJSON()));
|
||||
insomnia.environment.set('headerJson', JSON.stringify(header.toJSON()));
|
||||
`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
json: {
|
||||
evalResult: 16,
|
||||
hash: parsedUrl.hash,
|
||||
host: parsedUrl.host,
|
||||
hostname: parsedUrl.hostname,
|
||||
origin: parsedUrl.origin,
|
||||
password: parsedUrl.password,
|
||||
pathname: parsedUrl.pathname,
|
||||
port: parsedUrl.port,
|
||||
protocol: parsedUrl.protocol,
|
||||
search: parsedUrl.search,
|
||||
username: parsedUrl.username,
|
||||
searchParam: parsedUrl.searchParams.toString(),
|
||||
...Object.fromEntries(builtinModules.map((m) => [m, true])),
|
||||
...Object.fromEntries(externalModuleKeys.map((k) => [k, true])),
|
||||
builtInLodash: true,
|
||||
uuidNil: "00000000-0000-0000-0000-000000000000",
|
||||
propJson: { id: propertyId, name: propertyName, disabled: false },
|
||||
headerJson: { key: headerKey, value: headerValue, id: "", name: "" },
|
||||
},
|
||||
});
|
||||
});
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from '../../enums/http-method';
|
||||
import { ProjectType } from '../../enums/project-types';
|
||||
import { HTTP_SERVER, test } from '../../misc/fixtures';
|
||||
import { Collection } from '../../models/collection';
|
||||
import { Project } from '../../models/project';
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
|
||||
test('Verify pre-request script manipulates request headers, query params and body via insomnia.request', async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(new Project(faker.string.alphanumeric(10), ProjectType.Local));
|
||||
const collection = await workspaceFlow.createCollection(project, new Collection(faker.string.alphanumeric(10)));
|
||||
|
||||
const headerValue = faker.string.alphanumeric(10);
|
||||
const rawContent = faker.string.alphanumeric(10);
|
||||
const upsertedValue = faker.string.alphanumeric(10);
|
||||
const addedParam = faker.string.alphanumeric(10);
|
||||
const updatedParam = faker.string.alphanumeric(10);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${url}?removeMe=1&keepMe=2`,
|
||||
preRequestScript: `
|
||||
const { Header } = require('insomnia-collection');
|
||||
insomnia.request.headers.add(new Header({ key: 'X-Hello', value: '${headerValue}' }));
|
||||
insomnia.request.headers.add(new Header({ key: 'X-Remove', value: 'gone' }));
|
||||
insomnia.request.headers.upsert({ key: 'X-Upsert', value: '${upsertedValue}' });
|
||||
insomnia.request.headers.remove((header) => header.key === 'X-Remove');
|
||||
insomnia.request.url.addQueryParams('added=${addedParam}');
|
||||
insomnia.request.url.removeQueryParams('removeMe');
|
||||
insomnia.request.url.removeQueryParams('keepMe');
|
||||
insomnia.request.url.addQueryParams('keepMe=${updatedParam}');
|
||||
insomnia.request.body.update({ mode: 'raw', raw: '${rawContent}' });
|
||||
`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
data: rawContent,
|
||||
args: { added: addedParam, keepMe: updatedParam },
|
||||
headers: expect.objectContaining({
|
||||
'x-hello': headerValue,
|
||||
'x-upsert': upsertedValue,
|
||||
}),
|
||||
});
|
||||
expect((responseView.body as { args: Record<string, string>; headers: object }).args).not.toHaveProperty('removeMe');
|
||||
expect((responseView.body as { args: Record<string, string>; headers: object }).headers).not.toHaveProperty('x-remove');
|
||||
});
|
||||
|
||||
test('Verify pre-request script sets bearer auth via insomnia.request.auth', async ({ user }) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(new Project(faker.string.alphanumeric(10), ProjectType.Local));
|
||||
const collection = await workspaceFlow.createCollection(project, new Collection(faker.string.alphanumeric(10)));
|
||||
|
||||
const token = faker.string.alphanumeric(10);
|
||||
const prefix = faker.string.alpha(8);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
preRequestScript: `
|
||||
insomnia.request.auth.update({
|
||||
type: 'bearer',
|
||||
bearer: [
|
||||
{ key: 'token', value: '${token}' },
|
||||
{ key: 'prefix', value: '${prefix}' },
|
||||
],
|
||||
}, 'bearer');
|
||||
`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
headers: expect.objectContaining({
|
||||
authorization: `${prefix} ${token}`,
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
test('Verify pre-request script sets basic auth via insomnia.request.auth', async ({ user }) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(new Project(faker.string.alphanumeric(10), ProjectType.Local));
|
||||
const collection = await workspaceFlow.createCollection(project, new Collection(faker.string.alphanumeric(10)));
|
||||
|
||||
const username = faker.string.alphanumeric(10);
|
||||
const password = faker.string.alphanumeric(10);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
preRequestScript: `
|
||||
insomnia.request.auth.update({
|
||||
type: 'basic',
|
||||
basic: [
|
||||
{ key: 'username', value: '${username}' },
|
||||
{ key: 'password', value: '${password}' },
|
||||
],
|
||||
}, 'basic');
|
||||
`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
const expectedEncodedCredentials = Buffer.from(`${username}:${password}`, 'utf8').toString('base64');
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
headers: expect.objectContaining({
|
||||
authorization: `Basic ${expectedEncodedCredentials}`,
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
test('Verify pre-request script applies apikey, AWS v4, Hawk and OAuth 1.0 auth via insomnia.request.auth', async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(new Project(faker.string.alphanumeric(10), ProjectType.Local));
|
||||
const collection = await workspaceFlow.createCollection(project, new Collection(faker.string.alphanumeric(10)));
|
||||
|
||||
const apiKeyName = faker.string.alpha(8);
|
||||
const apiKeyValue = faker.string.alphanumeric(10);
|
||||
const accessKey = faker.string.alphanumeric(10);
|
||||
const secretKey = faker.string.alphanumeric(20);
|
||||
const region = faker.helpers.arrayElement(['us-east-1', 'eu-west-1']);
|
||||
const service = faker.string.alpha(6);
|
||||
const hawkId = faker.string.alphanumeric(10);
|
||||
const hawkKey = faker.string.alphanumeric(20);
|
||||
const consumerKey = faker.string.alphanumeric(10);
|
||||
const consumerSecret = faker.string.alphanumeric(10);
|
||||
|
||||
const authScripts = {
|
||||
apiKeyHeader: `insomnia.request.auth.update({ type: 'apikey', apikey: [{ key: 'key', value: '${apiKeyName}' }, { key: 'value', value: '${apiKeyValue}' }, { key: 'in', value: 'header' }] }, 'apikey');`,
|
||||
apiKeyQuery: `insomnia.request.auth.update({ type: 'apikey', apikey: [{ key: 'key', value: '${apiKeyName}' }, { key: 'value', value: '${apiKeyValue}' }, { key: 'in', value: 'queryParams' }] }, 'apikey');`,
|
||||
awsV4: `insomnia.request.auth.update({ type: 'awsv4', awsv4: [{ key: 'accessKey', value: '${accessKey}' }, { key: 'secretKey', value: '${secretKey}' }, { key: 'region', value: '${region}' }, { key: 'service', value: '${service}' }] }, 'awsv4');`,
|
||||
hawk: `insomnia.request.auth.update({ type: 'hawk', hawk: [{ key: 'authId', value: '${hawkId}' }, { key: 'authKey', value: '${hawkKey}' }, { key: 'algorithm', value: 'sha256' }] }, 'hawk');`,
|
||||
oauth1: `insomnia.request.auth.update({ type: 'oauth1', oauth1: [{ key: 'consumerKey', value: '${consumerKey}' }, { key: 'consumerSecret', value: '${consumerSecret}' }, { key: 'signatureMethod', value: 'HMAC-SHA1' }] }, 'oauth1');`,
|
||||
};
|
||||
const responses: Record<string, Awaited<ReturnType<typeof httpRequestFlow.send>>> = {};
|
||||
for (const [authName, preRequestScript] of Object.entries(authScripts)) {
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
preRequestScript,
|
||||
});
|
||||
responses[authName] = await httpRequestFlow.send(request);
|
||||
}
|
||||
|
||||
const headersOf = (name: string) => (responses[name].body as { headers: Record<string, string> }).headers;
|
||||
expect(headersOf('apiKeyHeader')).toMatchObject({
|
||||
[apiKeyName.toLowerCase()]: apiKeyValue,
|
||||
});
|
||||
expect(responses.apiKeyQuery.body).toMatchObject({
|
||||
args: { [apiKeyName]: apiKeyValue },
|
||||
});
|
||||
expect(headersOf('awsV4').authorization).toContain(`AWS4-HMAC-SHA256 Credential=${accessKey}/`);
|
||||
expect(headersOf('awsV4').authorization).toContain(`/${region}/${service}/`);
|
||||
expect(headersOf('hawk').authorization).toContain(`Hawk id="${hawkId}"`);
|
||||
expect(headersOf('oauth1').authorization).toContain(`oauth_consumer_key="${consumerKey}"`);
|
||||
expect(headersOf('oauth1').authorization).toContain('oauth_signature_method="HMAC-SHA1"');
|
||||
});
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ContentType } from "../../enums/content-type";
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
|
||||
test("Verify pre-request script's sendRequest serializes raw, urlencoded, graphql, and formdata bodies correctly", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const rawValue = faker.string.alphanumeric(10);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
body: {
|
||||
mimeType: ContentType.JSON,
|
||||
text: `{"results": {{ results }}}`,
|
||||
},
|
||||
preRequestScript: `
|
||||
const results = {};
|
||||
const modes = [
|
||||
{ key: 'raw', body: { mode: 'raw', raw: '${rawValue}' } },
|
||||
{ key: 'urlencoded', body: { mode: 'urlencoded', urlencoded: [{ key: 'a', value: '1' }, { key: 'b', value: '2' }] } },
|
||||
{ key: 'graphql', body: { mode: 'graphql', graphql: { query: '{ __typename }', variables: {} } } },
|
||||
{ key: 'formdata', body: { mode: 'formdata', formdata: [{ key: 'c', value: '3' }] } },
|
||||
];
|
||||
for (const m of modes) {
|
||||
const resp = await insomnia.sendRequest({ url: '${url}', method: 'POST', body: m.body });
|
||||
results[m.key] = resp.body;
|
||||
}
|
||||
insomnia.environment.set('results', JSON.stringify(results));
|
||||
`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
const results = (
|
||||
responseView.body as { json: { results: Record<string, string> } }
|
||||
).json.results;
|
||||
const raw = JSON.parse(results.raw);
|
||||
const urlencoded = JSON.parse(results.urlencoded);
|
||||
const graphql = JSON.parse(results.graphql);
|
||||
const formdata = JSON.parse(results.formdata);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(raw.data).toBe(rawValue);
|
||||
expect(urlencoded.data).toBe("a=1&b=2");
|
||||
expect(graphql.json).toMatchObject({
|
||||
query: "{ __typename }",
|
||||
variables: {},
|
||||
});
|
||||
expect(formdata.data).toContain("--X-INSOMNIA-BOUNDARY");
|
||||
expect(formdata.data).toContain('Content-Disposition: form-data; name="c"');
|
||||
expect(formdata.data).toContain("3");
|
||||
expect(formdata.data.trimEnd()).toMatch(/--X-INSOMNIA-BOUNDARY--$/);
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { ContentType } from "../../enums/content-type";
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import type { CurlCommand } from "../../models/curl-command";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
const body = `{"title": "${faker.string.alphanumeric(8)}"}`;
|
||||
const command = `curl -X QUERY "${url}" -H "Content-Type: application/json" -d '${body}'`;
|
||||
|
||||
test("Verify sending a QUERY request with a body", async ({ user }) => {
|
||||
const { httpRequestFlow, importFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const curl: CurlCommand = { command };
|
||||
await importFlow.importCurl(project, collection, curl);
|
||||
|
||||
const imported = await httpRequestFlow.get(url);
|
||||
const responseView = await httpRequestFlow.send(imported!);
|
||||
|
||||
expect(imported).toMatchObject({
|
||||
name: url,
|
||||
url,
|
||||
method: HttpMethod.Query,
|
||||
body: { mimeType: ContentType.JSON, text: body },
|
||||
} satisfies HttpRequest);
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({ data: body });
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { EnvironmentKvPairDataType } from "../../models/environment";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify query params from the URL, template tags, and the Parameters tab are merged and special characters are escaped correctly", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow, environmentFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const fromUrlValue = faker.string.alphanumeric(10);
|
||||
const fromEditorValue = faker.string.alphanumeric(10);
|
||||
const environment = await environmentFlow.createBaseEnvironment(project, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
kvPairData: [
|
||||
{
|
||||
id: "",
|
||||
name: "fromUrlValue",
|
||||
value: fromUrlValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "",
|
||||
name: "fromEditorValue",
|
||||
value: fromEditorValue,
|
||||
type: EnvironmentKvPairDataType.STRING,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
await environmentFlow.link(collection, environment);
|
||||
|
||||
const spaceValue = `${faker.string.alphanumeric(4)} ${faker.string.alphanumeric(4)}`;
|
||||
const ampersandValue = `${faker.string.alphanumeric(4)}&${faker.string.alphanumeric(4)}`;
|
||||
const equalsValue = `${faker.string.alphanumeric(4)}=${faker.string.alphanumeric(4)}`;
|
||||
const hashValue = `${faker.string.alphanumeric(4)}#${faker.string.alphanumeric(4)}`;
|
||||
const chineseValue = `测试${faker.string.alphanumeric(4)}参数`;
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post?key=fromUrl&key={{ fromUrlValue }}`,
|
||||
params: [
|
||||
{ name: "key", value: "{{ fromEditorValue }}" },
|
||||
{ name: "key", value: "/" },
|
||||
{ name: "space", value: spaceValue },
|
||||
{ name: "ampersand", value: ampersandValue },
|
||||
{ name: "equals", value: equalsValue },
|
||||
{ name: "hash", value: hashValue },
|
||||
{ name: "chinese", value: chineseValue },
|
||||
],
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
args: {
|
||||
key: ["fromUrl", fromUrlValue, fromEditorValue, "/"],
|
||||
space: spaceValue,
|
||||
ampersand: ampersandValue,
|
||||
equals: equalsValue,
|
||||
hash: hashValue,
|
||||
chinese: chineseValue,
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,76 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { DEFAULT_TIMEOUT, HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
|
||||
test("Verify insomnia.environment.replaceIn resolves and returns a string synchronously", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const variableName = faker.string.alpha(8);
|
||||
const variableValue = faker.string.alphanumeric(10);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
preRequestScript: `
|
||||
insomnia.environment.set('${variableName}', '${variableValue}');
|
||||
const v = insomnia.environment.replaceIn('{{ ${variableName} }}');
|
||||
console.log(typeof v, v);
|
||||
`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
await expect
|
||||
.poll(() => responseView.console?.(), { timeout: DEFAULT_TIMEOUT })
|
||||
.toContain(`log: string ${variableValue}`);
|
||||
const consoleText = await responseView.console?.();
|
||||
expect(consoleText).not.toContain("Promise");
|
||||
});
|
||||
|
||||
test("Verify a script that awaits insomnia.environment.replaceIn as a workaround still resolves correctly", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { httpRequestFlow, workspaceFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const variableName = faker.string.alpha(8);
|
||||
const variableValue = faker.string.alphanumeric(10);
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
preRequestScript: `
|
||||
insomnia.environment.set('${variableName}', '${variableValue}');
|
||||
const v = await insomnia.environment.replaceIn('{{ ${variableName} }}');
|
||||
console.log(typeof v, v);
|
||||
`,
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
|
||||
await expect
|
||||
.poll(() => responseView.console?.(), { timeout: DEFAULT_TIMEOUT })
|
||||
.toContain(`log: string ${variableValue}`);
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify the cookie Tag Reads a Value from a Linked Cookie", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow, cookieFlow, templateTagFlow } =
|
||||
user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
const cookieTag = `{% cookie '${HTTP_SERVER}', 'session' %}`;
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${HTTP_SERVER}/${cookieTag}`,
|
||||
});
|
||||
|
||||
const cookieValue = faker.string.alphanumeric(10);
|
||||
await cookieFlow.link(collection, [
|
||||
{ key: "session", value: cookieValue, domain: "localhost", path: "/" },
|
||||
]);
|
||||
await httpRequestFlow.get(request!.name);
|
||||
const tag = await templateTagFlow.get(cookieTag);
|
||||
|
||||
expect(tag.preview).toBe(cookieValue);
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify Switching an Existing Tag's Argument Updates its Live Preview", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow, templateTagFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
const hashTag = "{% hash 'md5', 'hex', 'hello' %}";
|
||||
await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${HTTP_SERVER}/${hashTag}`,
|
||||
});
|
||||
|
||||
const before = await templateTagFlow.get(hashTag);
|
||||
const after = await templateTagFlow.edit(hashTag, {
|
||||
functionName: "hash",
|
||||
algorithm: "sha256",
|
||||
digestEncoding: "hex",
|
||||
input: "hello",
|
||||
preview: "",
|
||||
});
|
||||
|
||||
expect(before.functionName).toBe("hash");
|
||||
expect(before.algorithm).toBe("md5");
|
||||
expect(before.preview).toBe("5d41402abc4b2a76b9719d911017c592");
|
||||
expect(after.algorithm).toBe("sha256");
|
||||
expect(after.preview).toBe(
|
||||
"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,110 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
import {
|
||||
AWSCredentialType,
|
||||
HashiCorpCredentialType,
|
||||
HashiCorpVaultAuthMethod,
|
||||
} from "insomnia-data";
|
||||
|
||||
import { ContentType } from "../../enums/content-type";
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import type { HttpRequest } from "../../models/http-request";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify AWS/GCP/HashiCorp Cloud Credentials Resolve via the Vault Template Tag", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow, templateTagFlow, preferencesFlow } =
|
||||
user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const awsCredentialName = faker.string.alphanumeric(10);
|
||||
const gcpCredentialName = faker.string.alphanumeric(10);
|
||||
const hashicorpCredentialName = faker.string.alphanumeric(10);
|
||||
await preferencesFlow.set({
|
||||
// Live Preview masks vault values as •••••• by default; the spec asserts the resolved value.
|
||||
hideSecretValuesInPreviewAndConsole: false,
|
||||
cloudCredentials: [
|
||||
{
|
||||
provider: "aws",
|
||||
name: awsCredentialName,
|
||||
credentials: {
|
||||
type: AWSCredentialType.file,
|
||||
section: faker.string.alphanumeric(8),
|
||||
region: faker.string.alphanumeric(8),
|
||||
},
|
||||
},
|
||||
{
|
||||
provider: "gcp",
|
||||
name: gcpCredentialName,
|
||||
credentials: { serviceAccountKeyFilePath: faker.system.filePath() },
|
||||
},
|
||||
{
|
||||
provider: "hashicorp",
|
||||
name: hashicorpCredentialName,
|
||||
credentials: {
|
||||
type: HashiCorpCredentialType.onPrem,
|
||||
authMethod: HashiCorpVaultAuthMethod.appRole,
|
||||
serverAddress: "http://127.0.0.1",
|
||||
role_id: faker.string.alphanumeric(8),
|
||||
secret_id: faker.string.alphanumeric(8),
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const awsTag = "{% vault 'aws', '', '{}' %}";
|
||||
const gcpTag = "{% vault 'gcp', '', '{}' %}";
|
||||
const hashicorpTag = "{% vault 'hashicorp', '', '{}' %}";
|
||||
const request = {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post`,
|
||||
body: {
|
||||
mimeType: ContentType.Plain,
|
||||
text: `${awsTag}\n${gcpTag}\n${hashicorpTag}`,
|
||||
},
|
||||
} satisfies HttpRequest;
|
||||
await httpRequestFlow.create(collection, request);
|
||||
|
||||
const awsResult = await templateTagFlow.edit(awsTag, {
|
||||
functionName: "vault",
|
||||
credentialName: awsCredentialName,
|
||||
preview: "",
|
||||
});
|
||||
const gcpResult = await templateTagFlow.edit(gcpTag, {
|
||||
functionName: "vault",
|
||||
credentialName: gcpCredentialName,
|
||||
preview: "",
|
||||
});
|
||||
const hashicorpResult = await templateTagFlow.edit(hashicorpTag, {
|
||||
functionName: "vault",
|
||||
credentialName: hashicorpCredentialName,
|
||||
preview: "",
|
||||
});
|
||||
|
||||
const responseView = await httpRequestFlow.send(request);
|
||||
const secondResponse = await httpRequestFlow.send(request);
|
||||
|
||||
expect(awsResult.preview).toBe("aws-secret-value");
|
||||
expect(gcpResult.preview).toBe("gcp-secret-value");
|
||||
expect(hashicorpResult.preview).toBe("hashicorp-secret-value");
|
||||
expect((responseView.body as { data: string }).data).toContain("aws-secret-value");
|
||||
expect((responseView.body as { data: string }).data).toContain("gcp-secret-value");
|
||||
expect((responseView.body as { data: string }).data).toContain(
|
||||
"hashicorp-secret-value",
|
||||
);
|
||||
expect((secondResponse.body as { data: string }).data).toContain(
|
||||
"aws-secret-value",
|
||||
);
|
||||
});
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
import path from "node:path";
|
||||
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../../enums/http-method";
|
||||
import { ProjectType } from "../../../enums/project-types";
|
||||
import { test } from "../../../misc/fixtures";
|
||||
import { Collection } from "../../../models/collection";
|
||||
import { Project } from "../../../models/project";
|
||||
|
||||
const filePath = path.join(__dirname, "fixture.txt");
|
||||
|
||||
test("Verify the file Tag Reads Contents from an Allowed Folder", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow, preferencesFlow, templateTagFlow } =
|
||||
user.flowManager;
|
||||
|
||||
await preferencesFlow.set({ dataFolders: [__dirname] });
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
const fileTag = `{% file '${filePath}' %}`;
|
||||
await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: fileTag,
|
||||
});
|
||||
|
||||
const result = await templateTagFlow.get(fileTag);
|
||||
|
||||
expect(result.preview).toBe("hello-from-file-tag");
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
hello-from-file-tag
|
||||
@@ -0,0 +1,54 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify Inserting a Template Tag and Reading its Live Preview", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow, templateTagFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const uuidTag = "{% uuid 'v4' %}";
|
||||
const base64Tag = "{% base64 'encode', 'normal', 'hello' %}";
|
||||
const nowTag = "{% now 'unix' %}";
|
||||
const fakerTag = "{% faker 'randomFirstName' %}";
|
||||
const jsonpathTag = "{% jsonpath '{\"a\":{\"b\":42}}', '$.a.b' %}";
|
||||
const osTag = "{% os 'platform' %}";
|
||||
const requestTag = "{% request 'name' %}";
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Get,
|
||||
url: `${uuidTag}${base64Tag}${nowTag}${fakerTag}${jsonpathTag}${osTag}${requestTag}`,
|
||||
});
|
||||
|
||||
const uuidResult = await templateTagFlow.get(uuidTag);
|
||||
const base64Result = await templateTagFlow.get(base64Tag);
|
||||
const nowResult = await templateTagFlow.get(nowTag);
|
||||
const fakerResult = await templateTagFlow.get(fakerTag);
|
||||
const jsonpathResult = await templateTagFlow.get(jsonpathTag);
|
||||
const osResult = await templateTagFlow.get(osTag);
|
||||
const requestResult = await templateTagFlow.get(requestTag);
|
||||
|
||||
expect(uuidResult.preview).toMatch(
|
||||
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/,
|
||||
);
|
||||
expect(base64Result.preview).toBe("aGVsbG8=");
|
||||
expect(nowResult.preview).toMatch(/^\d+$/);
|
||||
expect(fakerResult.preview).toMatch(/^[A-Za-z'-]+$/);
|
||||
expect(jsonpathResult.preview).toBe("42");
|
||||
expect(osResult.preview).toBe(process.platform);
|
||||
expect(requestResult.preview).toBe(request!.name);
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
test("Verify a Header With a Templated Name Resolves and Sends Correctly", async ({
|
||||
user,
|
||||
}) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url: `${HTTP_SERVER}/post`,
|
||||
headers: [
|
||||
{
|
||||
name: "X-{% hash 'md5', 'hex', 'header-name' %}",
|
||||
value: "plain-value",
|
||||
},
|
||||
],
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request!);
|
||||
|
||||
expect(responseView.statusCode).toBe(200);
|
||||
expect(responseView.body).toMatchObject({
|
||||
headers: expect.objectContaining({
|
||||
"x-7cd8e9f98e9104085ea06e39b87faf36": "plain-value",
|
||||
}),
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { HttpMethod } from "../../enums/http-method";
|
||||
import { ProjectType } from "../../enums/project-types";
|
||||
import { HTTP_SERVER, test } from "../../misc/fixtures";
|
||||
import { Collection } from "../../models/collection";
|
||||
import { Project } from "../../models/project";
|
||||
|
||||
const url = `${HTTP_SERVER}/post`;
|
||||
|
||||
test("Verify a Header With a Template Tag in Its Value", async ({ user }) => {
|
||||
const { workspaceFlow, httpRequestFlow } = user.flowManager;
|
||||
|
||||
const project = await workspaceFlow.createProject(
|
||||
new Project(faker.string.alphanumeric(10), ProjectType.Local),
|
||||
);
|
||||
const collection = await workspaceFlow.createCollection(
|
||||
project,
|
||||
new Collection(faker.string.alphanumeric(10)),
|
||||
);
|
||||
|
||||
const request = await httpRequestFlow.create(collection, {
|
||||
name: faker.string.alphanumeric(10),
|
||||
method: HttpMethod.Post,
|
||||
url,
|
||||
headers: [
|
||||
{
|
||||
name: "X-Header-Name",
|
||||
value: "{% base64 'encode', 'normal', 'header-value' %}",
|
||||
},
|
||||
],
|
||||
});
|
||||
const responseView = await httpRequestFlow.send(request!);
|
||||
|
||||
expect(responseView.body).toMatchObject({
|
||||
headers: expect.objectContaining({
|
||||
"x-header-name": "aGVhZGVyLXZhbHVl",
|
||||
}),
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user