Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/actions/getCookies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {assertValueIsDefined} from '../utils/asserts';

import type {Cookie} from '../types/internal';

const msInSecond = 1_000;

/**
* Returns page's cookies with the specified cookies parameters.
* If there are no cookies parameters, returns all the cookies.
Expand All @@ -24,8 +26,15 @@ export const getCookies = async (
await step(
logMessage,
async () => {
const page = getPlaywrightPage();
const allCookies = await page.context().cookies(page.url());
const playwrightPage = getPlaywrightPage();
const playwrightCookies = await playwrightPage.context().cookies(playwrightPage.url());

// Playwright's `cookies` returns `expires` in unix time in seconds (`-1` for session cookies),
// while `Cookie` type uses milliseconds (as in `Date.now()`).
const allCookies: readonly Cookie[] = playwrightCookies.map(({expires, ...cookie}) => ({
...cookie,
...(expires !== -1 ? {expires: expires * msInSecond} : undefined),
}));

if (parameters.length === 0) {
cookies = allCookies;
Expand Down
11 changes: 10 additions & 1 deletion src/actions/setCookies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {getPlaywrightPage} from '../useContext';

import type {Cookie} from '../types/internal';

const msInSecond = 1_000;

/**
* Set cookies with the specified cookies parameters.
*/
Expand All @@ -15,7 +17,14 @@ export const setCookies = (cookies: readonly Cookie[]): Promise<void> =>

const browserContext = page.context();

await browserContext.addCookies(cookies);
// Playwright's `addCookies` expects `expires` in unix time in seconds,
// while `Cookie` type uses milliseconds (as in `Date.now()`).
const playwrightCookies = cookies.map(({expires, ...cookie}) => ({
...cookie,
...(expires !== undefined ? {expires: Math.round(expires / msInSecond)} : undefined),
}));

await browserContext.addCookies(playwrightCookies);
},
{payload: {cookies}, type: LogEventType.InternalAction},
);
3 changes: 3 additions & 0 deletions src/types/http/cookie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import type {Brand} from '../brand';
*/
export type Cookie = Readonly<{
domain?: string;
/**
* Unix time in milliseconds (as in `Date.now()`).
*/
expires?: number;
httpOnly?: boolean;
name: string;
Expand Down
2 changes: 1 addition & 1 deletion src/types/http/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export type MapOptions = Readonly<{
* HTTP method.
*/
export type Method =
'CONNECT' | 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT' | 'TRACE';
'CONNECT' | 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT' | 'QUERY' | 'TRACE';

/**
* Object with query (search) part of the url, or query string itself.
Expand Down
2 changes: 2 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ export {deepMerge, getEntries, getKeys, setReadonlyProperty} from './object';
export {createPageObjectsFromMultiLocator} from './pageObjects';
export {
getCodeReport,
getFullStepDefinition,
getLinesIndexes,
getScenarioReference,
getStepReference,
getTestReference,
parseMaybeEmptyValueAsJson,
parseTest,
Expand Down
15 changes: 10 additions & 5 deletions src/utils/parse/codeReport/fillTestErrors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {getScenarioReference} from './getScenarioReference';
import {getScenarioStepsWithReference} from './getScenarioStepsWithReference';
import {getStepComparisonErrors} from './getStepComparisonErrors';
import {getStepReference} from './getStepReference';
import {getTestReference} from './getTestReference';
import {getTestStepsWithReference} from './getTestStepsWithReference';

Expand Down Expand Up @@ -28,17 +29,21 @@ export const fillTestErrors = (
for (const step of scenario.steps) {
if (step.definition === '') {
scenarioHasError = true;
errors.push(
`Step in ${scenario.featurePath}:${step.lineNumber + 1}:${step.column + 1} (in ${scenarioReference}) has no definition.`,

const reference = getStepReference(
{column: step.column + 1, line: step.lineNumber + 1},
scenario.featurePath,
);

errors.push(`Step ${reference} (in ${scenarioReference}) has no definition.`);
}
}

for (const step of test.steps) {
if (step.definition === undefined || step.definition === '') {
errors.push(
`Step in ${test.path}:${step.line}:${step.column} (in ${testReference}) has no definition.`,
);
const reference = getStepReference(step, test.path);

errors.push(`Step ${reference} (in ${testReference}) has no definition.`);
}
}

Expand Down
13 changes: 13 additions & 0 deletions src/utils/parse/codeReport/getFullStepDefinition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
type Step = Readonly<{
definition: string | undefined;
kind: string;
}>;

/**
* Get full definition of any step.
*/
export const getFullStepDefinition = ({definition, kind}: Step, count: number = 1): string => {
const fullDefinition = `"${kind}${definition === undefined || definition === '' ? '' : ` ${definition}`}"`;

return count > 1 ? `${fullDefinition} (occurrence ${count})` : fullDefinition;
};
13 changes: 9 additions & 4 deletions src/utils/parse/codeReport/getScenarioStepsWithReference.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {getFullStepDefinition} from './getFullStepDefinition';
import {getScenarioReference} from './getScenarioReference';
import {getStepReference} from './getStepReference';

import type {ScenarioReport, StepWithReference} from '../../../types/internal';

Expand All @@ -15,17 +17,20 @@ export const getScenarioStepsWithReference = (
const stepsHash: Record<string, number> = Object.create(null) as {};

for (const step of scenario.steps) {
const fullDefinition = `${step.kind} ${step.definition}`;
const fullDefinition = getFullStepDefinition(step);

stepsHash[fullDefinition] =
stepsHash[fullDefinition] === undefined ? 1 : stepsHash[fullDefinition] + 1;

const count = stepsHash[fullDefinition];
const reference = `in ${scenario.featurePath}:${step.lineNumber + 1}:${step.column + 1} (in ${scenarioReference})`;
const reference = getStepReference(
{column: step.column + 1, line: step.lineNumber + 1},
scenario.featurePath,
);

steps.push({
key: count === 1 ? `"${fullDefinition}"` : `"${fullDefinition}" (occurrence ${count})`,
reference,
key: getFullStepDefinition(step, count),
reference: `${reference} (in ${scenarioReference})`,
});
}

Expand Down
10 changes: 10 additions & 0 deletions src/utils/parse/codeReport/getStepReference.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
type Step = Readonly<{
column: number;
line: number;
}>;

/**
* Get step reference (without step definition).
*/
export const getStepReference = ({column, line}: Step, path: string): string =>
`in ${path}:${line}:${column}`;
9 changes: 6 additions & 3 deletions src/utils/parse/codeReport/getTestStepsWithReference.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import {getFullStepDefinition} from './getFullStepDefinition';
import {getStepReference} from './getStepReference';

import type {StepWithReference, TestReport} from '../../../types/internal';

/**
Expand All @@ -13,16 +16,16 @@ export const getTestStepsWithReference = (test: TestReport): readonly StepWithRe
continue;
}

const fullDefinition = `${step.kind} ${step.definition}`;
const fullDefinition = getFullStepDefinition(step);

stepsHash[fullDefinition] =
stepsHash[fullDefinition] === undefined ? 1 : stepsHash[fullDefinition] + 1;

const count = stepsHash[fullDefinition];
const reference = `in ${test.path}:${step.line}:${step.column}`;
const reference = getStepReference(step, test.path);

steps.push({
key: count === 1 ? `"${fullDefinition}"` : `"${fullDefinition}" (occurrence ${count})`,
key: getFullStepDefinition(step, count),
reference,
});
}
Expand Down
2 changes: 2 additions & 0 deletions src/utils/parse/codeReport/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export {getCodeReport} from './getCodeReport';
export {getFullStepDefinition} from './getFullStepDefinition';
export {getScenarioReference} from './getScenarioReference';
export {getStepReference} from './getStepReference';
export {getTestReference} from './getTestReference';
8 changes: 7 additions & 1 deletion src/utils/parse/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
export {getCodeReport, getScenarioReference, getTestReference} from './codeReport';
export {
getCodeReport,
getFullStepDefinition,
getScenarioReference,
getStepReference,
getTestReference,
} from './codeReport';
export {parseMaybeEmptyValueAsJson} from './parseMaybeEmptyValueAsJson';
export {getLinesIndexes, parseTest, ParseTestError} from './parseTest';
export {parseValueAsJsonIfNeeded} from './parseValueAsJsonIfNeeded';