Skip to content
This repository has been archived by the owner on Jul 2, 2024. It is now read-only.

DEVPROD-1904 Fix flaky test caused by racing assertions and Introduce realClick for clipboard events #438

Merged
merged 8 commits into from
Nov 17, 2023
Merged
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
43 changes: 17 additions & 26 deletions cypress/integration/ansiLogs/ansi_logView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,12 @@ describe("Bookmarking and selecting lines", () => {
const logLine297 =
"[2022/03/02 17:05:21.050] running setup group because we have a new independent task";

cy.dataCy("details-button").click();
cy.dataCy("jira-button").click();
cy.window().then((win) => {
win.navigator.clipboard.readText().then((text) => {
expect(text).to.eq(
`{noformat}\n${logLine0}\n...\n${logLine10}\n${logLine11}\n...\n${logLine297}\n{noformat}`
);
});
});
cy.toggleDetailsPanel(true);
// Need to fire a real click here because the copy to clipboard
cy.dataCy("jira-button").realClick();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to create a clipboard interaction helper command that calls realClick and asserts the value. I can tell the logic should be consolidated because of the repeated comment that explains special usage

cy.assertValueCopiedToClipboard(
`{noformat}\n${logLine0}\n...\n${logLine10}\n${logLine11}\n...\n${logLine297}\n{noformat}`
);
});

it("should be able to clear bookmarks", () => {
Expand Down Expand Up @@ -207,7 +204,7 @@ describe("Sharing lines", () => {

beforeEach(() => {
cy.visit(logLink);
cy.dataCy("line-index-1").should("be.visible");
cy.dataCy("line-index-1").should("exist").should("be.visible");
});

it("should present a share button with a menu when a line is selected", () => {
Expand All @@ -226,30 +223,24 @@ describe("Sharing lines", () => {
cy.dataCy("line-index-2").click({ shiftKey: true });
cy.dataCy("sharing-menu").should("be.visible");
cy.contains("Copy selected contents").should("be.visible");
cy.contains("Copy selected contents").click();
// Need to fire a real click here because the copy to clipboard
cy.contains("Copy selected contents").realClick();
cy.validateToast("success", "Copied 2 lines to clipboard", true);
cy.window().then((win) => {
win.navigator.clipboard.readText().then((text) => {
expect(text).to.eq(
`{noformat}\n[2022/03/02 17:01:58.587] Task logger initialized (agent version 2022-02-14 from 00a4c8f3e8e4559cc23e04a019b6d1725c40c3e5).\n...\n[2022/03/02 17:02:01.610] e391612 EVG-16049 Update spruce project page for admin only variables (#1114)\n[2022/03/02 17:02:01.610] 04a52b2 EVG-15959 Fix rerender method in test utils (#1118)\n...\n[2022/03/02 17:05:21.050] running setup group because we have a new independent task\n{noformat}`
);
});
});
cy.assertValueCopiedToClipboard(
`{noformat}\n[2022/03/02 17:01:58.587] Starting task spruce_ubuntu1604_test_2c9056df66d42fb1908d52eed096750a91f1f089_22_03_02_16_45_12, execution 0.\n[2022/03/02 17:01:58.701] Running pre-task commands.\n{noformat}`
);
});
it("should be able to copy a link to the selected lines", () => {
cy.dataCy("line-index-1").click();
cy.dataCy("line-index-2").click({ shiftKey: true });
cy.dataCy("sharing-menu").should("be.visible");
cy.contains("Copy share link to selected lines").should("be.visible");
cy.contains("Copy share link to selected lines").click();
// Need to fire a real click here because the copy to clipboard
cy.contains("Copy share link to selected lines").realClick();
cy.validateToast("success", "Copied link to clipboard", true);
cy.window().then((win) => {
win.navigator.clipboard.readText().then((text) => {
expect(text).to.eq(
"http://localhost:4173/evergreen/spruce_ubuntu1604_test_2c9056df66d42fb1908d52eed096750a91f1f089_22_03_02_16_45_12/0/task?bookmarks=0%2C297&selectedLineRange=L1-L2&shareLine=1"
);
});
});
cy.assertValueCopiedToClipboard(
"http://localhost:4173/evergreen/spruce_ubuntu1604_test_2c9056df66d42fb1908d52eed096750a91f1f089_22_03_02_16_45_12/0/task?bookmarks=0%2C297&selectedLineRange=L1-L2&shareLine=1"
);
});
it("should be able to limit the search range to the selected lines", () => {
cy.dataCy("line-index-1").click();
Expand Down
40 changes: 15 additions & 25 deletions cypress/integration/resmokeLogs/resmoke_logView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,11 @@ describe("Bookmarking and selecting lines", () => {
const logLine11079 = `[j0:s1] | 2022-09-21T12:50:28.489+00:00 I NETWORK 22944 [conn60] "Connection ended","attr":{"remote":"127.0.0.1:47362","uuid":{"uuid":{"$uuid":"b28d7d9f-03b6-4f93-a7cd-5e1948135f69"}},"connectionId":60,"connectionCount":2}`;

cy.dataCy("details-button").click();
cy.dataCy("jira-button").click();
cy.window().then((win) => {
win.navigator.clipboard.readText().then((text) => {
expect(text).to.eq(
`{noformat}\n${logLine0}\n...\n${logLine10}\n${logLine11}\n...\n${logLine11079}\n{noformat}`
);
});
});
// Need to fire a real click here because the copy to clipboard
cy.dataCy("jira-button").realClick();
cy.assertValueCopiedToClipboard(
`{noformat}\n${logLine0}\n...\n${logLine10}\n${logLine11}\n...\n${logLine11079}\n{noformat}`
);
});

it("should be able to clear bookmarks", () => {
Expand Down Expand Up @@ -289,31 +286,24 @@ describe("Sharing lines", () => {
cy.dataCy("line-index-2").click({ shiftKey: true });
cy.dataCy("sharing-menu").should("be.visible");
cy.contains("Copy selected contents").should("be.visible");
cy.contains("Copy selected contents").click();
// Need to fire a real click here because the copy to clipboard
cy.contains("Copy selected contents").realClick();
cy.validateToast("success", "Copied 2 lines to clipboard", true);
cy.window().then((win) => {
win.navigator.clipboard.readText().then((text) => {
expect(text).to.eq(
`{noformat}\n+------------------------------------------+--------+-----+-----+\n|full_name |name |port |pid |\n{noformat}`
);
});
});
cy.assertValueCopiedToClipboard(
`{noformat}\n+------------------------------------------+--------+-----+-----+\n|full_name |name |port |pid |\n{noformat}`
);
});
it("should be able to copy a link to the selected lines", () => {
cy.dataCy("line-index-1").click();
cy.dataCy("line-index-2").click({ shiftKey: true });
cy.dataCy("sharing-menu").should("be.visible");
cy.contains("Copy share link to selected lines").should("be.visible");
cy.contains("Copy share link to selected lines").click();
// Need to fire a real click here because the copy to clipboard
cy.contains("Copy share link to selected lines").realClick();
cy.validateToast("success", "Copied link to clipboard", true);
cy.window().then((win) => {
win.navigator.clipboard.readText().then((text) => {
cy.log("text", text);
expect(text).to.eq(
"http://localhost:4173/resmoke/7e208050e166b1a9025c817b67eee48d/test/1716e11b4f8a4541c5e2faf70affbfab?bookmarks=0%2C11079&selectedLineRange=L1-L2&shareLine=1"
);
});
});
cy.assertValueCopiedToClipboard(
"http://localhost:4173/resmoke/7e208050e166b1a9025c817b67eee48d/test/1716e11b4f8a4541c5e2faf70affbfab?bookmarks=0%2C11079&selectedLineRange=L1-L2&shareLine=1"
);
});
it("should be able to limit the search range to the selected lines", () => {
cy.dataCy("line-index-1").click();
Expand Down
11 changes: 11 additions & 0 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,14 @@ Cypress.Commands.add(
}
}
);

Cypress.Commands.add("assertValueCopiedToClipboard", (value: string) => {
cy.window().then((win) => {
win.navigator.clipboard.readText().then((text) => {
expect(text).to.eq(value);
});
});
// This wait is necessary to ensure the clipboard has time to be read
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(50);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine by me!!

});
6 changes: 6 additions & 0 deletions cypress/support/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import "cypress-real-events";
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is required and initializes the package for the entire test suite.

import "./commands";

declare global {
Expand Down Expand Up @@ -90,6 +91,11 @@ declare global {
message?: string,
shouldClose?: boolean
): void;
/**
* Custom command to validate that a value was copied to the clipboard.
* @example cy.assertValueCopiedToClipboard("This is some text")
*/
assertValueCopiedToClipboard(text: string): void;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions cypress/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"compilerOptions": {
"target": "ES5",
"lib": ["ES5", "DOM"],
"types": ["cypress", "node"],
"types": ["cypress", "node", "cypress-real-events"],
},
"include": ["**/*.ts"]
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
"babel-loader": "8.2.5",
"babel-plugin-import-graphql": "2.8.1",
"cypress": "12.7.0",
"cypress-real-events": "1.11.0",
"env-cmd": "10.1.0",
"eslint": "8.31.0",
"eslint-config-airbnb": "19.0.4",
Expand Down
3 changes: 2 additions & 1 deletion src/components/LogRow/AnsiRow/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AnsiUp } from "ansi_up";
import linkifyHtml from "linkify-html";
import BaseRow from "components/LogRow/BaseRow";
import { trimSeverity } from "utils/string";
import { getSeverityMapping, mapLogLevelToColor } from "./utils";
import { LogRowProps } from "../types";

Expand All @@ -21,7 +22,7 @@ const AnsiRow: React.FC<AnsiRowProps> = ({ getLine, lineNumber, ...rest }) => {

if (severity) {
// Trim "[P: NN] " priority prefix
lineContent = lineContent.substring(8);
lineContent = trimSeverity(lineContent);
}

const linkifiedLine = linkifyHtml(ansiUp.ansi_to_html(lineContent ?? ""), {
Expand Down
35 changes: 35 additions & 0 deletions src/gql/generated/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ export type Distro = {
iceCreamSettings: IceCreamSettings;
isCluster: Scalars["Boolean"]["output"];
isVirtualWorkStation: Scalars["Boolean"]["output"];
mountpoints: Array<Maybe<Scalars["String"]["output"]>>;
name: Scalars["String"]["output"];
note: Scalars["String"]["output"];
plannerSettings: PlannerSettings;
Expand Down Expand Up @@ -1048,6 +1049,7 @@ export type Mutation = {
scheduleTasks: Array<Task>;
scheduleUndispatchedBaseTasks?: Maybe<Array<Task>>;
setAnnotationMetadataLinks: Scalars["Boolean"]["output"];
setLastRevision: SetLastRevisionPayload;
setPatchPriority?: Maybe<Scalars["String"]["output"]>;
/** setPatchVisibility takes a list of patch ids and a boolean to set the visibility on the my patches queries */
setPatchVisibility: Array<Patch>;
Expand Down Expand Up @@ -1273,6 +1275,10 @@ export type MutationSetAnnotationMetadataLinksArgs = {
taskId: Scalars["String"]["input"];
};

export type MutationSetLastRevisionArgs = {
opts: SetLastRevisionInput;
};

export type MutationSetPatchPriorityArgs = {
patchId: Scalars["String"]["input"];
priority: Scalars["Int"]["input"];
Expand Down Expand Up @@ -1539,13 +1545,18 @@ export type Permissions = {
canCreateProject: Scalars["Boolean"]["output"];
canEditAdminSettings: Scalars["Boolean"]["output"];
distroPermissions: DistroPermissions;
projectPermissions: ProjectPermissions;
userId: Scalars["String"]["output"];
};

export type PermissionsDistroPermissionsArgs = {
options: DistroPermissionsOptions;
};

export type PermissionsProjectPermissionsArgs = {
options: ProjectPermissionsOptions;
};

export type PlannerSettings = {
__typename?: "PlannerSettings";
commitQueueFactor: Scalars["Int"]["output"];
Expand Down Expand Up @@ -1819,6 +1830,16 @@ export type ProjectInput = {
workstationConfig?: InputMaybe<WorkstationConfigInput>;
};

export type ProjectPermissions = {
__typename?: "ProjectPermissions";
edit: Scalars["Boolean"]["output"];
view: Scalars["Boolean"]["output"];
};

export type ProjectPermissionsOptions = {
projectIdentifier: Scalars["String"]["input"];
};

/** ProjectSettings models the settings for a given Project. */
export type ProjectSettings = {
__typename?: "ProjectSettings";
Expand Down Expand Up @@ -2280,6 +2301,20 @@ export type SelectorInput = {
type: Scalars["String"]["input"];
};

/**
* SetLastRevisionInput is the input to the setLastRevision mutation.
* It contains information used to fix the repotracker error of a project.
*/
export type SetLastRevisionInput = {
projectIdentifier: Scalars["String"]["input"];
revision: Scalars["String"]["input"];
};

export type SetLastRevisionPayload = {
__typename?: "SetLastRevisionPayload";
mergeBaseRevision: Scalars["String"]["output"];
};

export type SlackConfig = {
__typename?: "SlackConfig";
name?: Maybe<Scalars["String"]["output"]>;
Expand Down
14 changes: 13 additions & 1 deletion src/utils/string/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const getJiraFormat = (
break;
}

jiraString += `${logText}\n`;
jiraString += `${trimSeverity(logText)}\n`;

// If the current and next indices are not adjacent to each other, insert an
// ellipsis in between them.
Expand Down Expand Up @@ -115,3 +115,15 @@ export const trimLogLineToMaxSize = (line: string, maxSize: number) => {
}
return line;
};

/**
* `trimSeverity` trims the severity prefix from a line
* @param line - the line to trim
* @returns - the line without the severity prefix
*/
export const trimSeverity = (line: string) => {
if (line.startsWith("[P: ")) {
return line.substring(8);
}
return line;
};
30 changes: 30 additions & 0 deletions src/utils/string/string.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
shortenGithash,
stringIntersection,
trimLogLineToMaxSize,
trimSeverity,
trimStringFromMiddle,
} from ".";

Expand Down Expand Up @@ -130,3 +131,32 @@ describe("trimLogLineToMaxSize", () => {
expect(trimLogLineToMaxSize("1234", 3)).toBe("123…");
});
});

describe("trimSeverity", () => {
it("should trim the severity prefix from a line", () => {
expect(
trimSeverity(
"[P: 40] [2022/12/05 20:03:30.136] Running pre-task commands."
)
).toBe("[2022/12/05 20:03:30.136] Running pre-task commands.");
expect(
trimSeverity(
"[P: 70] [2022/12/05 20:03:30.138] + '[' amazon2-cloud-small = amazon2-cloud-large ']'"
)
).toBe(
"[2022/12/05 20:03:30.138] + '[' amazon2-cloud-small = amazon2-cloud-large ']'"
);
});
it("should not trim the string if the severity prefix is not present", () => {
expect(
trimSeverity("[2022/12/05 20:03:30.136] Running pre-task commands.")
).toBe("[2022/12/05 20:03:30.136] Running pre-task commands.");
expect(
trimSeverity(
"[2022/12/05 20:03:30.138] + '[' amazon2-cloud-small = amazon2-cloud-large ']'"
)
).toBe(
"[2022/12/05 20:03:30.138] + '[' amazon2-cloud-small = amazon2-cloud-large ']'"
);
});
});
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7792,6 +7792,11 @@ csstype@^3.0.2:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2"
integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==

[email protected]:
version "1.11.0"
resolved "https://registry.yarnpkg.com/cypress-real-events/-/cypress-real-events-1.11.0.tgz#292fe5281c5b6e955524e766ab7fec46930c7763"
integrity sha512-4LXVRsyq+xBh5TmlEyO1ojtBXtN7xw720Pwb9rEE9rkJuXmeH3VyoR1GGayMGr+Itqf11eEjfDewtDmcx6PWPQ==

[email protected]:
version "12.7.0"
resolved "https://registry.yarnpkg.com/cypress/-/cypress-12.7.0.tgz#69900f82af76cf3ba0ddb9b59ec3b0d38222ab22"
Expand Down