diff --git a/.evergreen.yml b/.evergreen.yml index 3fc61bdf59..020c49467f 100644 --- a/.evergreen.yml +++ b/.evergreen.yml @@ -392,6 +392,7 @@ functions: script: | echo "Generating .env-cmdrc.json" REACT_APP_BUGSNAG_API_KEY=${REACT_APP_BUGSNAG_API_KEY} \ + REACT_APP_SENTRY_AUTH_TOKEN=${REACT_APP_SENTRY_AUTH_TOKEN} \ REACT_APP_SENTRY_DSN=${REACT_APP_SENTRY_DSN} \ REACT_APP_NEW_RELIC_ACCOUNT_ID=${REACT_APP_NEW_RELIC_ACCOUNT_ID} \ REACT_APP_NEW_RELIC_AGENT_ID=${REACT_APP_NEW_RELIC_AGENT_ID} \ diff --git a/src/setupTests.ts b/config/jest/setupTests.ts similarity index 53% rename from src/setupTests.ts rename to config/jest/setupTests.ts index 4b9d1f902a..712d9679d3 100644 --- a/src/setupTests.ts +++ b/config/jest/setupTests.ts @@ -2,7 +2,7 @@ // allows you to do things like: // expect(element).toHaveTextContent(/react/i) // learn more: https://github.com/testing-library/jest-dom -import "@testing-library/jest-dom/extend-expect"; +import "@testing-library/jest-dom"; import MutationObserver from "mutation-observer"; // @ts-ignore @@ -16,3 +16,16 @@ window.crypto.randomUUID = (() => { return value.toString(); }; })(); + +// Mock focus-trap-react to prevent errors in tests that use modals. focus-trap-react is a package used +// by LeafyGreen and is not a direct dependency of Spruce. +jest.mock( + "focus-trap-react", + () => { + const focusTrap = jest.requireActual( + "focus-trap-react" + ); + focusTrap.prototype.setupFocusTrap = () => null; + return focusTrap; + } +); diff --git a/cypress/integration/commit_queue.ts b/cypress/integration/commit_queue.ts index 0c73f08cc1..e05f0d5221 100644 --- a/cypress/integration/commit_queue.ts +++ b/cypress/integration/commit_queue.ts @@ -3,13 +3,11 @@ const commitQueue = { id2: "mongodb-mongo-test", id3: "non-existent-item", id4: "evergreen", - id5: "logkeeper", }; const COMMIT_QUEUE_ROUTE_1 = `/commit-queue/${commitQueue.id1}`; const COMMIT_QUEUE_ROUTE_2 = `/commit-queue/${commitQueue.id2}`; const INVALID_COMMIT_QUEUE_ROUTE = `/commit-queue/${commitQueue.id3}`; const COMMIT_QUEUE_ROUTE_4 = `/commit-queue/${commitQueue.id4}`; -const COMMIT_QUEUE_ROUTE_PR = `/commit-queue/${commitQueue.id5}`; describe("commit queue page", { testIsolation: false }, () => { describe(COMMIT_QUEUE_ROUTE_1, () => { @@ -84,32 +82,4 @@ describe("commit queue page", { testIsolation: false }, () => { cy.validateToast("error", "There was an error loading the commit queue"); }); }); - - describe(COMMIT_QUEUE_ROUTE_PR, () => { - before(() => { - cy.visit(COMMIT_QUEUE_ROUTE_PR); - }); - it("Clicking on remove a patch for the PR commit queue should work", () => { - cy.dataCy("commit-queue-card").should("have.length", 1); - cy.dataCy("commit-queue-card-title").should( - "have.text", - "patch description here" - ); - cy.dataCy("commit-queue-card-title").within(() => { - cy.get("a").should( - "have.attr", - "href", - "https://github.com/logkeeper/logkeeper/pull/1234" - ); - }); - cy.dataCy("commit-queue-patch-button").should("exist"); - cy.dataCy("commit-queue-patch-button").click(); - cy.dataCy("commit-queue-confirmation-modal").should("be.visible"); - cy.dataCy("commit-queue-confirmation-modal").within(() => { - cy.contains("Remove").click(); - }); - cy.dataCy("commit-queue-confirmation-modal").should("not.exist"); - cy.dataCy("commit-queue-card").should("not.exist"); - }); - }); }); diff --git a/cypress/integration/distroSettings/provider_section.ts b/cypress/integration/distroSettings/provider_section.ts new file mode 100644 index 0000000000..740ad09c89 --- /dev/null +++ b/cypress/integration/distroSettings/provider_section.ts @@ -0,0 +1,38 @@ +import { save } from "./utils"; + +describe("provider section", () => { + beforeEach(() => { + cy.visit("/distro/localhost/settings/provider"); + }); + + it("successfully updates static provider fields", () => { + cy.dataCy("provider-select").contains("Static IP/VM"); + + // Correct fields are displayed + cy.dataCy("provider-settings").within(() => { + cy.get("button").should("have.length", 1); + cy.get("textarea").should("have.length", 1); + cy.get("input[type=checkbox]").should("have.length", 1); + cy.get("input[type=text]").should("have.length", 0); + }); + + cy.getInputByLabel("User Data").type("my user data"); + cy.getInputByLabel("Merge with existing user data").check({ + force: true, + }); + cy.contains("button", "Add security group").click(); + cy.getInputByLabel("Security Group ID").type("group-1234"); + + save(); + cy.validateToast("success"); + + cy.getInputByLabel("User Data").clear(); + cy.getInputByLabel("Merge with existing user data").uncheck({ + force: true, + }); + cy.dataCy("delete-item-button").click(); + + save(); + cy.validateToast("success"); + }); +}); diff --git a/cypress/integration/projectSettings/project_settings.ts b/cypress/integration/projectSettings/project_settings.ts index abd154aa03..a6a4e52cc6 100644 --- a/cypress/integration/projectSettings/project_settings.ts +++ b/cypress/integration/projectSettings/project_settings.ts @@ -197,7 +197,7 @@ describe("Repo Settings", { testIsolation: false }, () => { countCQFields(2); cy.dataCy("cq-enabled-radio-box").children().first().click(); - countCQFields(7); + countCQFields(4); cy.dataCy("error-banner") .contains( @@ -206,8 +206,16 @@ describe("Repo Settings", { testIsolation: false }, () => { .should("exist"); }); - it("Presents three options for merge method", () => { + it("Shows merge method only if merge queue is Evergreen", () => { const selectId = "merge-method-select"; + + // Hides merge method for GitHub. + cy.getInputByLabel("GitHub").check({ force: true }); + cy.dataCy(selectId).should("not.exist"); + + // Shows merge method for Evergreen. + cy.getInputByLabel("Evergreen").check({ force: true }); + cy.dataCy(selectId).should("exist"); cy.get(`button[name=${selectId}]`).click(); cy.get(`#${selectId}-menu`).children().should("have.length", 3); cy.get(`#${selectId}-menu`).children().first().click(); diff --git a/jest.config.js b/jest.config.js index f0f0cc4332..dac2467599 100644 --- a/jest.config.js +++ b/jest.config.js @@ -14,7 +14,7 @@ module.exports = { modulePaths: ["/src"], resetMocks: true, setupFiles: ["react-app-polyfill/jsdom", "jest-canvas-mock"], - setupFilesAfterEnv: ["/src/setupTests.ts"], + setupFilesAfterEnv: ["/config/jest/setupTests.ts"], snapshotSerializers: ["@emotion/jest/serializer"], testEnvironment: "jsdom", testMatch: ["/{src,scripts}/**/*.{spec,test}.{js,jsx,ts,tsx}"], @@ -40,7 +40,5 @@ module.exports = { "jest-watch-typeahead/testname", ], globalSetup: "/global-setup.js", - globals: { - APP_VERSION: JSON.stringify(process.env.npm_package_version), - }, + testTimeout: 30000, }; diff --git a/package.json b/package.json index eca3557f8a..000b77b042 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "spruce", - "version": "3.0.128", + "version": "3.0.132", "private": true, "scripts": { "bootstrap-logkeeper": "./scripts/bootstrap-logkeeper.sh", @@ -57,7 +57,7 @@ "@apollo/client": "3.6.9", "@bugsnag/js": "7.20.2", "@bugsnag/plugin-react": "7.18.0", - "@emotion/css": "11.11.0", + "@emotion/css": "11.11.2", "@emotion/react": "11.11.0", "@emotion/styled": "11.11.0", "@leafygreen-ui/badge": "8.0.2", @@ -137,11 +137,12 @@ "@emotion/babel-plugin": "11.11.0", "@emotion/eslint-plugin": "11.11.0", "@emotion/jest": "11.11.0", - "@graphql-codegen/cli": "3.2.2", - "@graphql-codegen/typescript": "3.0.2", - "@graphql-codegen/typescript-operations": "3.0.2", + "@graphql-codegen/cli": "5.0.0", + "@graphql-codegen/typescript": "4.0.1", + "@graphql-codegen/typescript-operations": "4.0.1", "@graphql-eslint/eslint-plugin": "3.18.0", "@originjs/vite-plugin-commonjs": "1.0.3", + "@sentry/vite-plugin": "2.6.2", "@storybook/addon-actions": "7.0.21", "@storybook/addon-essentials": "7.0.21", "@storybook/addon-interactions": "7.0.21", @@ -151,10 +152,9 @@ "@storybook/react-vite": "7.0.21", "@storybook/testing-library": "0.2.0", "@styled/typescript-styled-plugin": "1.0.0", - "@testing-library/jest-dom": "5.16.4", - "@testing-library/react": "12.1.5", - "@testing-library/react-hooks": "8.0.0", - "@testing-library/user-event": "12.5.0", + "@testing-library/jest-dom": "6.1.2", + "@testing-library/react": "14.0.0", + "@testing-library/user-event": "14.4.3", "@types/jest": "29.4.0", "@types/js-cookie": "^3.0.2", "@types/lodash.debounce": "4.0.7", diff --git a/scripts/setup-credentials.js b/scripts/setup-credentials.js index b5c535b7b6..3e03c06d8b 100644 --- a/scripts/setup-credentials.js +++ b/scripts/setup-credentials.js @@ -13,6 +13,7 @@ const production = { REACT_APP_SPRUCE_URL: "https://spruce.mongodb.com", REACT_APP_RELEASE_STAGE: "production", REACT_APP_BUGSNAG_API_KEY: process.env.REACT_APP_BUGSNAG_API_KEY, + REACT_APP_SENTRY_AUTH_TOKEN: process.env.REACT_APP_SENTRY_AUTH_TOKEN, REACT_APP_SENTRY_DSN: process.env.REACT_APP_SENTRY_DSN, REACT_APP_NEW_RELIC_ACCOUNT_ID: process.env.REACT_APP_NEW_RELIC_ACCOUNT_ID, REACT_APP_NEW_RELIC_AGENT_ID: process.env.REACT_APP_NEW_RELIC_AGENT_ID, diff --git a/src/components/Breadcrumbs/Breadcrumbs.test.tsx b/src/components/Breadcrumbs/Breadcrumbs.test.tsx index 23e8f2a672..51ed1f2112 100644 --- a/src/components/Breadcrumbs/Breadcrumbs.test.tsx +++ b/src/components/Breadcrumbs/Breadcrumbs.test.tsx @@ -21,6 +21,7 @@ describe("breadcrumbs", () => { expect(screen.queryAllByDataCy("breadcrumb-chevron")).toHaveLength(1); }); it("breadcrumbs with long text should be collapsed and viewable with a tooltip", async () => { + const user = userEvent.setup(); const longMessage = "some really long string that could be a patch title"; const breadcrumbs = [{ text: longMessage }]; render(); @@ -29,31 +30,29 @@ describe("breadcrumbs", () => { expect( screen.getByText(trimStringFromMiddle(longMessage, 30)) ).toBeInTheDocument(); - userEvent.hover(screen.getByText(trimStringFromMiddle(longMessage, 30))); + await user.hover(screen.getByText(trimStringFromMiddle(longMessage, 30))); await waitFor(() => { expect(screen.getByDataCy("breadcrumb-tooltip")).toBeInTheDocument(); }); expect(screen.getByText(longMessage)).toBeInTheDocument(); }); it("should not display a tooltip if the text is short", async () => { + const user = userEvent.setup(); const shortMessage = "short"; const breadcrumbs = [{ text: shortMessage }]; render(); expect(screen.getByText(shortMessage)).toBeInTheDocument(); - userEvent.hover(screen.getByText(shortMessage)); - await waitFor(() => { - expect( - screen.queryByDataCy("breadcrumb-tooltip") - ).not.toBeInTheDocument(); - }); + await user.hover(screen.getByText(shortMessage)); + expect(screen.queryByDataCy("breadcrumb-tooltip")).not.toBeInTheDocument(); }); - it("clicking on a tooltip with a link and event handler should call the event", () => { + it("clicking on a tooltip with a link and event handler should call the event", async () => { + const user = userEvent.setup(); const onClick = jest.fn(); const breadcrumbs = [{ text: "test", onClick, to: "/" }]; render(); expect(screen.getByText("test")).toBeInTheDocument(); expect(screen.getByRole("link")).toHaveAttribute("href", "/"); - userEvent.click(screen.getByText("test")); + await user.click(screen.getByText("test")); expect(onClick).toHaveBeenCalledTimes(1); }); }); diff --git a/src/components/CommitChartLabel/CommitChartLabel.test.tsx b/src/components/CommitChartLabel/CommitChartLabel.test.tsx index d2e94dcec5..b5db97b803 100644 --- a/src/components/CommitChartLabel/CommitChartLabel.test.tsx +++ b/src/components/CommitChartLabel/CommitChartLabel.test.tsx @@ -24,7 +24,8 @@ describe("commitChartLabel", () => { it("displays author, githash and createTime", () => { renderWithRouterMatch(); expect(screen.queryByDataCy("commit-label")).toHaveTextContent( - "4137c33 Jun 16, 2021, 11:38 PM Mohamed Khelif" + "4137c33 Jun 16, 2021, 11:38 PM Mohamed Khelif -SERVER-57332 Create skeleton Internal" + + "Git Tags: v1.2.3, v1.2.3-rc0" ); }); @@ -50,7 +51,8 @@ describe("commitChartLabel", () => { renderWithRouterMatch(); expect(screen.getByText("more")).toBeInTheDocument(); expect(screen.queryByDataCy("commit-label")).toHaveTextContent( - "4137c33 Jun 16, 2021, 11:38 PM Mohamed Khelif -SERVER-57332 Create skeleton Internal...more" + "4137c33 Jun 16, 2021, 11:38 PM Mohamed Khelif -SERVER-57332 Create skeleton Internal...more" + + "Git Tags: v1.2.3, v1.2.3-rc0" ); }); @@ -62,11 +64,11 @@ describe("commitChartLabel", () => { }); it("clicking on the 'more' button should open a tooltip containing commit message", async () => { + const user = userEvent.setup(); renderWithRouterMatch(); expect(screen.queryByDataCy("long-commit-message-tooltip")).toBeNull(); - userEvent.click(screen.queryByText("more")); - + await user.click(screen.queryByText("more")); await waitFor(() => { expect( screen.getByDataCy("long-commit-message-tooltip") diff --git a/src/components/Dropdown/Dropdown.test.tsx b/src/components/Dropdown/Dropdown.test.tsx index ad7a91e56b..641451d315 100644 --- a/src/components/Dropdown/Dropdown.test.tsx +++ b/src/components/Dropdown/Dropdown.test.tsx @@ -9,33 +9,39 @@ describe("dropdown", () => { expect(screen.queryByText("Some Children")).not.toBeInTheDocument(); }); - it("clicking on the button opens and closes the dropdown", () => { + it("clicking on the button opens and closes the dropdown", async () => { + const user = userEvent.setup(); render( {children()} ); - expect(screen.getByText("Some Button")).toBeInTheDocument(); + const button = screen.getByRole("button", { name: "Some Button" }); + expect(button).toBeInTheDocument(); expect(screen.queryByText("Some Children")).not.toBeInTheDocument(); - userEvent.click(screen.queryByText("Some Button")); + await user.click(button); expect(screen.getByText("Some Children")).toBeInTheDocument(); - userEvent.click(screen.queryByText("Some Button")); + await user.click(button); expect(screen.queryByText("Some Children")).not.toBeInTheDocument(); }); - it("clicking on the dropdown contents should not close the dropdown", () => { + it("clicking on the dropdown contents should not close the dropdown", async () => { + const user = userEvent.setup(); render( {children()} ); - expect(screen.getByText("Some Button")).toBeInTheDocument(); + const button = screen.getByRole("button", { name: "Some Button" }); + expect(button).toBeInTheDocument(); expect(screen.queryByText("Some Children")).not.toBeInTheDocument(); - userEvent.click(screen.queryByText("Some Button")); + await user.click(button); expect(screen.getByText("Some Children")).toBeInTheDocument(); - userEvent.click(screen.queryByText("Some Children")); + await user.click(screen.queryByText("Some Children")); expect(screen.getByText("Some Children")).toBeInTheDocument(); }); - it("clicking outside the button and dropdown closes the dropdown", () => { + it("clicking outside the button and dropdown closes the dropdown", async () => { + const user = userEvent.setup(); render( {children()} ); - expect(screen.getByText("Some Button")).toBeInTheDocument(); + const button = screen.getByRole("button", { name: "Some Button" }); + expect(button).toBeInTheDocument(); expect(screen.queryByText("Some Children")).not.toBeInTheDocument(); - userEvent.click(screen.queryByText("Some Button")); + await user.click(button); expect(screen.getByText("Some Children")).toBeInTheDocument(); - userEvent.click(document.body); + await user.click(document.body); expect(screen.queryByText("Some Children")).not.toBeInTheDocument(); }); diff --git a/src/components/EditableTagField/EditableTagField.test.tsx b/src/components/EditableTagField/EditableTagField.test.tsx index 95d834efef..4f1090ed77 100644 --- a/src/components/EditableTagField/EditableTagField.test.tsx +++ b/src/components/EditableTagField/EditableTagField.test.tsx @@ -42,6 +42,7 @@ describe("editableTagField", () => { data = x; }); + const user = userEvent.setup(); render( { expect(data).toStrictEqual(defaultData); expect(screen.queryAllByDataCy("user-tag-trash-icon")[0]).toBeVisible(); - userEvent.clear(screen.queryAllByDataCy("user-tag-value-field")[0]); - userEvent.type( + await user.clear(screen.queryAllByDataCy("user-tag-value-field")[0]); + await user.type( screen.queryAllByDataCy("user-tag-value-field")[0], "new value" ); expect(screen.queryAllByDataCy("user-tag-edit-icon")[0]).toBeVisible(); - userEvent.click(screen.queryAllByDataCy("user-tag-edit-icon")[0]); + await user.click(screen.queryAllByDataCy("user-tag-edit-icon")[0]); expect(updateData).toHaveBeenCalledWith([ { key: "keyA", value: "new value" }, @@ -78,6 +79,7 @@ describe("editableTagField", () => { data = x; }); + const user = userEvent.setup(); render( { expect(data).toStrictEqual(defaultData); expect(screen.queryAllByDataCy("user-tag-trash-icon")[0]).toBeVisible(); - userEvent.click(screen.queryAllByDataCy("user-tag-trash-icon")[0]); + await user.click(screen.queryAllByDataCy("user-tag-trash-icon")[0]); expect(updateData).toHaveBeenCalledWith([...defaultData.slice(1, 3)]); expect(data).toStrictEqual([...defaultData.slice(1, 3)]); @@ -102,6 +104,7 @@ describe("editableTagField", () => { data = x; }); + const user = userEvent.setup(); render( { expect(data).toStrictEqual(defaultData); expect(screen.queryAllByDataCy("user-tag-trash-icon")[0]).toBeVisible(); - userEvent.clear(screen.queryAllByDataCy("user-tag-key-field")[0]); - userEvent.type(screen.queryAllByDataCy("user-tag-key-field")[0], "new key"); + await user.clear(screen.queryAllByDataCy("user-tag-key-field")[0]); + await user.type( + screen.queryAllByDataCy("user-tag-key-field")[0], + "new key" + ); expect(screen.queryAllByDataCy("user-tag-edit-icon")[0]).toBeVisible(); - userEvent.click(screen.queryAllByDataCy("user-tag-edit-icon")[0]); + await user.click(screen.queryAllByDataCy("user-tag-edit-icon")[0]); expect(updateData).toHaveBeenCalledWith([ { ...defaultData[0], key: "new key" }, @@ -135,6 +141,7 @@ describe("editableTagField", () => { data = x; }); + const user = userEvent.setup(); render( { expect(screen.queryAllByDataCy("user-tag-row")).toHaveLength(3); expect(screen.queryByDataCy("add-tag-button")).toBeVisible(); - userEvent.click(screen.queryByDataCy("add-tag-button")); + await user.click(screen.queryByDataCy("add-tag-button")); expect(screen.queryByDataCy("add-tag-button")).toBeNull(); expect(screen.queryAllByDataCy("user-tag-trash-icon")[3]).toBeVisible(); expect(screen.queryAllByDataCy("user-tag-row")).toHaveLength(4); - userEvent.clear(screen.queryAllByDataCy("user-tag-key-field")[3]); - userEvent.type(screen.queryAllByDataCy("user-tag-key-field")[3], "new key"); + await user.clear(screen.queryAllByDataCy("user-tag-key-field")[3]); + await user.type( + screen.queryAllByDataCy("user-tag-key-field")[3], + "new key" + ); - userEvent.clear(screen.queryAllByDataCy("user-tag-value-field")[3]); - userEvent.type( + await user.clear(screen.queryAllByDataCy("user-tag-value-field")[3]); + await user.type( screen.queryAllByDataCy("user-tag-value-field")[3], "new value" ); expect(screen.queryAllByDataCy("user-tag-edit-icon")).toHaveLength(1); - userEvent.click(screen.queryAllByDataCy("user-tag-edit-icon")[0]); + await user.click(screen.queryAllByDataCy("user-tag-edit-icon")[0]); expect(updateData).toHaveBeenCalledTimes(1); expect(data).toStrictEqual([ diff --git a/src/components/ErrorHandling/Sentry.tsx b/src/components/ErrorHandling/Sentry.tsx index 9a84034c76..84dc73db0d 100644 --- a/src/components/ErrorHandling/Sentry.tsx +++ b/src/components/ErrorHandling/Sentry.tsx @@ -18,7 +18,6 @@ const initializeSentry = () => { dsn: getSentryDSN(), debug: !isProduction(), normalizeDepth: 5, - release: APP_VERSION, environment: releaseStage, }); } catch (e) { diff --git a/src/components/ErrorHandling/initialize.test.ts b/src/components/ErrorHandling/initialize.test.ts index d0286529b0..74414562cb 100644 --- a/src/components/ErrorHandling/initialize.test.ts +++ b/src/components/ErrorHandling/initialize.test.ts @@ -47,7 +47,6 @@ describe("should initialize error handlers according to release stage", () => { dsn: "fake-sentry-key", debug: false, normalizeDepth: 5, - release: APP_VERSION, environment: "production", }); }); @@ -71,7 +70,6 @@ describe("should initialize error handlers according to release stage", () => { dsn: "fake-sentry-key", debug: true, normalizeDepth: 5, - release: APP_VERSION, environment: "beta", }); }); @@ -95,7 +93,6 @@ describe("should initialize error handlers according to release stage", () => { dsn: "fake-sentry-key", debug: true, normalizeDepth: 5, - release: APP_VERSION, environment: "staging", }); }); diff --git a/src/components/FilterBadges/FilterBadges.test.tsx b/src/components/FilterBadges/FilterBadges.test.tsx index 5302ef5b73..e6215326b4 100644 --- a/src/components/FilterBadges/FilterBadges.test.tsx +++ b/src/components/FilterBadges/FilterBadges.test.tsx @@ -12,13 +12,11 @@ describe("filterBadges", () => { }); it("should render badges if there are some passed in", () => { - const onRemove = jest.fn(); - const onClearAll = jest.fn(); render( ); expect(screen.queryAllByDataCy("filter-badge")).toHaveLength(1); @@ -26,16 +24,14 @@ describe("filterBadges", () => { }); it("should render a badge for each key/value pair passed in", () => { - const onRemove = jest.fn(); - const onClearAll = jest.fn(); render( ); expect(screen.queryAllByDataCy("filter-badge")).toHaveLength(2); @@ -44,8 +40,6 @@ describe("filterBadges", () => { }); it("only renders badges up to the limit", () => { - const onRemove = jest.fn(); - const onClearAll = jest.fn(); render( { { key: "test9", value: "value9" }, { key: "test10", value: "value10" }, ]} - onRemove={onRemove} - onClearAll={onClearAll} + onRemove={jest.fn()} + onClearAll={jest.fn()} /> ); expect(screen.queryAllByDataCy("filter-badge")).toHaveLength(8); @@ -70,9 +64,8 @@ describe("filterBadges", () => { expect(screen.getByText("see 2 more")).toBeInTheDocument(); }); - it("clicking see more should display a modal with all of the badges", () => { - const onRemove = jest.fn(); - const onClearAll = jest.fn(); + it("clicking see more should display a modal with all of the badges", async () => { + const user = userEvent.setup(); render( { { key: "test9", value: "value9" }, { key: "test10", value: "value10" }, ]} - onRemove={onRemove} - onClearAll={onClearAll} + onRemove={jest.fn()} + onClearAll={jest.fn()} /> ); - userEvent.click(screen.queryByText("see 2 more")); + await user.click(screen.queryByText("see 2 more")); expect(screen.getByDataCy("see-more-modal")).toBeInTheDocument(); expect( within(screen.queryByDataCy("see-more-modal")).queryAllByDataCy( @@ -107,8 +100,8 @@ describe("filterBadges", () => { } }); - it("clicking clear all should call the clear all callback", () => { - const onRemove = jest.fn(); + it("clicking clear all should call the clear all callback", async () => { + const user = userEvent.setup(); const onClearAll = jest.fn(); render( { { key: "test9", value: "value9" }, { key: "test10", value: "value10" }, ]} - onRemove={onRemove} + onRemove={jest.fn()} onClearAll={onClearAll} /> ); - userEvent.click(screen.queryByText("CLEAR ALL FILTERS")); + await user.click(screen.getByRole("button", { name: "CLEAR ALL FILTERS" })); expect(onClearAll).toHaveBeenCalledTimes(1); }); - it("clicking a badge should call the remove callback", () => { + it("clicking a badge should call the remove callback", async () => { + const user = userEvent.setup(); const onRemove = jest.fn(); - const onClearAll = jest.fn(); render( { { key: "test10", value: "value10" }, ]} onRemove={onRemove} - onClearAll={onClearAll} + onClearAll={jest.fn()} /> ); const closeBadge = screen.queryAllByDataCy("close-badge")[0]; expect(closeBadge).toBeInTheDocument(); - userEvent.click(closeBadge); + await user.click(closeBadge); expect(onRemove).toHaveBeenCalledWith({ key: "test1", value: "value1" }); }); it("should truncate a badge value if it is too long", async () => { - const onRemove = jest.fn(); - const onClearAll = jest.fn(); + const user = userEvent.setup(); const longName = "this is a really long name that should be truncated"; render( ); const truncatedBadge = screen.queryByDataCy("filter-badge"); expect(truncatedBadge).toBeInTheDocument(); expect(truncatedBadge).not.toHaveTextContent(longName); - userEvent.hover(truncatedBadge); + await user.hover(truncatedBadge); await waitFor(() => { expect(screen.queryByText(longName)).toBeVisible(); }); diff --git a/src/components/FilterBadges/useFilterBadgeQueryParams.test.tsx b/src/components/FilterBadges/useFilterBadgeQueryParams.test.tsx index 9f8b13da3d..dc4ab3b1e3 100644 --- a/src/components/FilterBadges/useFilterBadgeQueryParams.test.tsx +++ b/src/components/FilterBadges/useFilterBadgeQueryParams.test.tsx @@ -58,7 +58,8 @@ describe("filterBadges - queryParams", () => { expect(badges[1]).toHaveTextContent("tests: test1"); }); - it("closing out a badge should remove it from the url", () => { + it("closing out a badge should remove it from the url", async () => { + const user = userEvent.setup(); const { router } = render(, { route: "/commits/evergreen?buildVariants=variant1", path: "/commits/:projectId", @@ -68,13 +69,14 @@ describe("filterBadges - queryParams", () => { expect(badge).toHaveTextContent("buildVariants: variant1"); const closeBadge = screen.queryByDataCy("close-badge"); expect(closeBadge).toBeInTheDocument(); - userEvent.click(closeBadge); + await user.click(closeBadge); expect(screen.queryByDataCy("filter-badge")).toBeNull(); expect(router.state.location.search).toBe(""); }); - it("should only remove one badge from the url if it is closed and more remain", () => { + it("should only remove one badge from the url if it is closed and more remain", async () => { + const user = userEvent.setup(); const { router } = render(, { route: "/commits/evergreen?buildVariants=variant1,variant2", path: "/commits/:projectId", @@ -84,7 +86,7 @@ describe("filterBadges - queryParams", () => { expect(badges).toHaveLength(2); expect(screen.getByText("buildVariants: variant1")).toBeInTheDocument(); const closeBadge = screen.queryAllByDataCy("close-badge"); - userEvent.click(closeBadge[0]); + await user.click(closeBadge[0]); badges = screen.queryAllByDataCy("filter-badge"); expect(badges).toHaveLength(1); expect(screen.queryByText("buildVariants: variant1")).toBeNull(); @@ -93,7 +95,8 @@ describe("filterBadges - queryParams", () => { expect(router.state.location.search).toBe("?buildVariants=variant2"); }); - it("should remove all badges when clicking on clear all button", () => { + it("should remove all badges when clicking on clear all button", async () => { + const user = userEvent.setup(); const { router } = render(, { route: "/commits/evergreen?buildVariants=variant1,variant2&tests=test1,test2", @@ -103,14 +106,15 @@ describe("filterBadges - queryParams", () => { let badges = screen.queryAllByDataCy("filter-badge"); expect(badges).toHaveLength(4); - userEvent.click(screen.queryByDataCy("clear-all-filters")); + await user.click(screen.queryByDataCy("clear-all-filters")); badges = screen.queryAllByDataCy("filter-badge"); expect(badges).toHaveLength(0); expect(router.state.location.search).toBe(""); }); - it("should only remove query params for displayable badges when clear all is pressed", () => { + it("should only remove query params for displayable badges when clear all is pressed", async () => { + const user = userEvent.setup(); const { router } = render(, { route: "/commits/evergreen?buildVariants=variant1,variant2&tests=test1,test2¬Related=notRelated", @@ -120,7 +124,7 @@ describe("filterBadges - queryParams", () => { let badges = screen.queryAllByDataCy("filter-badge"); expect(badges).toHaveLength(4); - userEvent.click(screen.queryByDataCy("clear-all-filters")); + await user.click(screen.queryByDataCy("clear-all-filters")); badges = screen.queryAllByDataCy("filter-badge"); expect(badges).toHaveLength(0); diff --git a/src/components/GroupedTaskStatusBadge/GroupedTaskStatusBadge.test.tsx b/src/components/GroupedTaskStatusBadge/GroupedTaskStatusBadge.test.tsx index 87d1d58198..eab9fd0eb5 100644 --- a/src/components/GroupedTaskStatusBadge/GroupedTaskStatusBadge.test.tsx +++ b/src/components/GroupedTaskStatusBadge/GroupedTaskStatusBadge.test.tsx @@ -9,7 +9,10 @@ import { TaskStatus } from "types/task"; import { GroupedTaskStatusBadge } from "."; describe("groupedTaskStatusBadgeIcon", () => { - it("clicking on badge performs an action", () => { + const versionId = "version1"; + + it("clicking on badge performs an action", async () => { + const user = userEvent.setup(); const onClick = jest.fn(); render( { ); const badge = screen.queryByDataCy("grouped-task-status-badge"); expect(badge).toBeInTheDocument(); - userEvent.click(badge); + await user.click(badge); expect(onClick).toHaveBeenCalledWith(); }); @@ -58,6 +61,7 @@ describe("groupedTaskStatusBadgeIcon", () => { }); it("badge should show tooltip when status counts is provided", async () => { + const user = userEvent.setup(); const statusCounts = { started: 30, failed: 15, @@ -76,18 +80,12 @@ describe("groupedTaskStatusBadgeIcon", () => { screen.queryByDataCy("grouped-task-status-badge-tooltip") ).toBeNull(); }); - userEvent.hover(screen.queryByDataCy("grouped-task-status-badge")); - + await user.hover(screen.queryByDataCy("grouped-task-status-badge")); await waitFor(() => { expect( screen.getByDataCy("grouped-task-status-badge-tooltip") ).toBeInTheDocument(); }); - await waitFor(() => { - expect( - screen.queryByDataCy("grouped-task-status-badge-tooltip") - ).toBeVisible(); - }); expect(screen.queryByText("30")).toBeVisible(); expect(screen.queryByText("Running")).toBeVisible(); expect(screen.queryByText("5")).toBeVisible(); @@ -95,5 +93,4 @@ describe("groupedTaskStatusBadgeIcon", () => { expect(screen.queryByText("15")).toBeVisible(); expect(screen.queryByText("Failed")).toBeVisible(); }); - const versionId = "version1"; }); diff --git a/src/components/Header/NavDropdown/NavDropdown.test.tsx b/src/components/Header/NavDropdown/NavDropdown.test.tsx index f74a5b96c4..d1cfbfb907 100644 --- a/src/components/Header/NavDropdown/NavDropdown.test.tsx +++ b/src/components/Header/NavDropdown/NavDropdown.test.tsx @@ -1,4 +1,4 @@ -import { screen, renderWithRouterMatch as render, waitFor } from "test_utils"; +import { screen, renderWithRouterMatch as render, userEvent } from "test_utils"; import { NavDropdown } from "."; const menuItems = [ @@ -20,19 +20,17 @@ describe("navDropdown", () => { expect(screen.getByText("Dropdown")).toBeInTheDocument(); }); it("opening the dropdown renders all of the buttons", async () => { + const user = userEvent.setup(); render(); - screen.getByText("Dropdown").click(); - await waitFor(() => { - expect(screen.getByText("Item 1")).toBeInTheDocument(); - }); + await user.click(screen.getByText("Dropdown")); + expect(screen.getByText("Item 1")).toBeInTheDocument(); expect(screen.getByText("Item 2")).toBeInTheDocument(); }); it("should link to both router and non-router links", async () => { + const user = userEvent.setup(); render(); - screen.getByText("Dropdown").click(); - await waitFor(() => { - expect(screen.getByText("Item 1")).toBeInTheDocument(); - }); + await user.click(screen.getByText("Dropdown")); + expect(screen.getByText("Item 1")).toBeInTheDocument(); expect(screen.getByText("Item 1").closest("a")).toHaveAttribute( "href", "/item1" @@ -43,6 +41,7 @@ describe("navDropdown", () => { ); }); it("clicking on a link triggers a callback", async () => { + const user = userEvent.setup(); const mockCallback = jest.fn(); render( { ]} /> ); - screen.getByText("Dropdown").click(); - await waitFor(() => { - expect(screen.getByText("Item 1")).toBeInTheDocument(); - }); - screen.getByText("Item 1").click(); + await user.click(screen.getByText("Dropdown")); + expect(screen.getByText("Item 1")).toBeInTheDocument(); + await user.click(screen.getByText("Item 1")); expect(mockCallback).toHaveBeenCalledWith(); }); }); diff --git a/src/components/HistoryTable/Cell/Cell.test.tsx b/src/components/HistoryTable/Cell/Cell.test.tsx index c70d7ddec1..0217c95474 100644 --- a/src/components/HistoryTable/Cell/Cell.test.tsx +++ b/src/components/HistoryTable/Cell/Cell.test.tsx @@ -74,6 +74,7 @@ describe("taskCell", () => { }); it("should have a tooltip on hover with failing tests when they are supplied", async () => { + const user = userEvent.setup(); render( { loading={false} /> ); - userEvent.hover(screen.queryByDataCy("history-table-icon")); + await user.hover(screen.queryByDataCy("history-table-icon")); await screen.findByText("some-test"); expect(screen.getByDataCy("test-tooltip")).toBeInTheDocument(); expect(screen.getByText("some-test")).toBeInTheDocument(); diff --git a/src/components/HistoryTable/HistoryTableContext.test.tsx b/src/components/HistoryTable/HistoryTableContext.test.tsx index f39fca3b9b..7456505433 100644 --- a/src/components/HistoryTable/HistoryTableContext.test.tsx +++ b/src/components/HistoryTable/HistoryTableContext.test.tsx @@ -1,4 +1,4 @@ -import { renderHook, act } from "@testing-library/react-hooks"; +import { renderHook, act } from "test_utils"; import { HistoryTableProvider, useHistoryTable } from "./HistoryTableContext"; import { columns, mainlineCommitData } from "./testData"; import { rowType, CommitRowType } from "./types"; diff --git a/src/components/HistoryTable/HistoryTableIcon/HistoryTableIcon.test.tsx b/src/components/HistoryTable/HistoryTableIcon/HistoryTableIcon.test.tsx index 329cc964fd..3328db1067 100644 --- a/src/components/HistoryTable/HistoryTableIcon/HistoryTableIcon.test.tsx +++ b/src/components/HistoryTable/HistoryTableIcon/HistoryTableIcon.test.tsx @@ -3,26 +3,29 @@ import { TaskStatus } from "types/task"; import { HistoryTableIcon } from "."; describe("historyTableIcon", () => { - it("clicking on the icon performs an action", () => { + it("clicking on the icon performs an action", async () => { + const user = userEvent.setup(); const onClick = jest.fn(); render( ); const icon = screen.queryByDataCy("history-table-icon"); expect(icon).toBeInTheDocument(); - userEvent.click(icon); + await user.click(icon); expect(onClick).toHaveBeenCalledWith(); }); - it("hovering over the icon when there no failing tests shouldn't open a tooltip", () => { + it("hovering over the icon when there no failing tests shouldn't open a tooltip", async () => { + const user = userEvent.setup(); render(); const icon = screen.queryByDataCy("history-table-icon"); expect(icon).toBeInTheDocument(); - userEvent.hover(icon); + await user.hover(icon); expect(screen.queryByText("test a")).not.toBeInTheDocument(); }); it("hovering over the icon when there are failing tests should open a tooltip", async () => { + const user = userEvent.setup(); render( { ); const icon = screen.queryByDataCy("history-table-icon"); expect(icon).toBeInTheDocument(); - userEvent.hover(icon); + await user.hover(icon); await waitFor(() => { expect(screen.queryByText("test a")).toBeVisible(); }); diff --git a/src/components/HistoryTable/HistoryTableRow/BaseRow/FoldedCommit/FoldedCommit.test.tsx b/src/components/HistoryTable/HistoryTableRow/BaseRow/FoldedCommit/FoldedCommit.test.tsx index c0742354ab..6739e181c7 100644 --- a/src/components/HistoryTable/HistoryTableRow/BaseRow/FoldedCommit/FoldedCommit.test.tsx +++ b/src/components/HistoryTable/HistoryTableRow/BaseRow/FoldedCommit/FoldedCommit.test.tsx @@ -1,6 +1,6 @@ import { MockedProvider } from "@apollo/client/testing"; import { getSpruceConfigMock } from "gql/mocks/getSpruceConfig"; -import { renderWithRouterMatch as render, screen } from "test_utils"; +import { renderWithRouterMatch as render, userEvent, screen } from "test_utils"; import FoldedCommit from "."; import { foldedCommitData } from "./testData"; @@ -28,7 +28,7 @@ describe("foldedCommit", () => { expect(screen.queryByText("Collapse 5 inactive")).toBeNull(); }); - it("can be expanded to show all of the commits", () => { + it("can be expanded to show all of the commits", async () => { const data = { ...foldedCommitData, }; @@ -36,6 +36,7 @@ describe("foldedCommit", () => { data.expanded = expanded; }); + const user = userEvent.setup(); render( { /> ); - screen.queryByText("Expand 5 inactive").click(); + await user.click(screen.queryByText("Expand 5 inactive")); expect(screen.queryByText("Expand 5 inactive")).toBeNull(); expect(screen.getByText("Collapse 5 inactive")).toBeInTheDocument(); expect(onToggleFoldedCommit).toHaveBeenCalledWith({ diff --git a/src/components/HistoryTable/HistoryTableTestSearch/HistoryTableTestSearch.test.tsx b/src/components/HistoryTable/HistoryTableTestSearch/HistoryTableTestSearch.test.tsx index a0aa9e5c19..0c9db75e37 100644 --- a/src/components/HistoryTable/HistoryTableTestSearch/HistoryTableTestSearch.test.tsx +++ b/src/components/HistoryTable/HistoryTableTestSearch/HistoryTableTestSearch.test.tsx @@ -15,7 +15,8 @@ describe("historyTableTestSearch", () => { expect(input).toHaveValue(""); }); - it("should clear input when a value is submitted", () => { + it("should clear input when a value is submitted", async () => { + const user = userEvent.setup(); render(, { route: `/variant-history/evergreen/lint`, path: "/variant-history/:projectId/:variantName", @@ -25,13 +26,14 @@ describe("historyTableTestSearch", () => { ) as HTMLInputElement; expect(input).toHaveValue(""); - userEvent.type(input, "some-test-name"); + await user.type(input, "some-test-name"); expect(input).toHaveValue("some-test-name"); - userEvent.type(input, "{enter}"); + await user.type(input, "{enter}"); expect(input).toHaveValue(""); }); - it("should add input query params to the url", () => { + it("should add input query params to the url", async () => { + const user = userEvent.setup(); const { router } = render(, { route: `/variant-history/evergreen/lint`, path: "/variant-history/:projectId/:variantName", @@ -42,13 +44,14 @@ describe("historyTableTestSearch", () => { // FAILED TEST expect(input).toHaveValue(""); - userEvent.type(input, "some-test-name"); + await user.type(input, "some-test-name"); expect(input).toHaveValue("some-test-name"); - userEvent.type(input, "{enter}"); + await user.type(input, "{enter}"); expect(router.state.location.search).toBe(`?failed=some-test-name`); }); - it("should add multiple input filters to the same key as query params", () => { + it("should add multiple input filters to the same key as query params", async () => { + const user = userEvent.setup(); const { router } = render(, { route: `/variant-history/evergreen/lint`, path: "/variant-history/:projectId/:variantName", @@ -57,18 +60,19 @@ describe("historyTableTestSearch", () => { "Search test name regex" ) as HTMLInputElement; expect(input).toHaveValue(""); - userEvent.type(input, "some-test-name"); + await user.type(input, "some-test-name"); expect(input).toHaveValue("some-test-name"); - userEvent.type(input, "{enter}"); - userEvent.type(input, "some-other-test-name"); + await user.type(input, "{enter}"); + await user.type(input, "some-other-test-name"); expect(input).toHaveValue("some-other-test-name"); - userEvent.type(input, "{enter}"); + await user.type(input, "{enter}"); expect(router.state.location.search).toBe( `?failed=some-test-name,some-other-test-name` ); }); - it("should not allow duplicate input filters for the same key as query params", () => { + it("should not allow duplicate input filters for the same key as query params", async () => { + const user = userEvent.setup(); const { router } = render(, { route: `/variant-history/evergreen/lint`, path: "/variant-history/:projectId/:variantName", @@ -77,12 +81,12 @@ describe("historyTableTestSearch", () => { "Search test name regex" ) as HTMLInputElement; expect(input).toHaveValue(""); - userEvent.type(input, "some-test-name"); + await user.type(input, "some-test-name"); expect(input).toHaveValue("some-test-name"); - userEvent.type(input, "{enter}"); - userEvent.type(input, "some-test-name"); + await user.type(input, "{enter}"); + await user.type(input, "some-test-name"); expect(input).toHaveValue("some-test-name"); - userEvent.type(input, "{enter}"); + await user.type(input, "{enter}"); expect(router.state.location.search).toBe(`?failed=some-test-name`); }); }); diff --git a/src/components/HistoryTable/hooks/useTestResults.test.tsx b/src/components/HistoryTable/hooks/useTestResults.test.tsx index 742ad2187f..bd7da8c9d5 100644 --- a/src/components/HistoryTable/hooks/useTestResults.test.tsx +++ b/src/components/HistoryTable/hooks/useTestResults.test.tsx @@ -1,9 +1,9 @@ -import { act, renderHook } from "@testing-library/react-hooks"; import { TaskTestSampleQuery, TaskTestSampleQueryVariables, } from "gql/generated/types"; import { GET_TASK_TEST_SAMPLE } from "gql/queries"; +import { act, renderHook, waitFor } from "test_utils"; import { ApolloMock } from "types/gql"; import { TestStatus } from "types/history"; import { useHistoryTable } from "../HistoryTableContext"; @@ -65,12 +65,9 @@ describe("useTestResults", () => { }); it("should return all matching test results when there are no filters applied and the row is a commit", async () => { - const { result, waitForNextUpdate } = renderHook( - () => useMergedTestHook(1), - { - wrapper: ({ children }) => ProviderWrapper({ children, mocks }), - } - ); + const { result } = renderHook(() => useMergedTestHook(1), { + wrapper: ({ children }) => ProviderWrapper({ children, mocks }), + }); expect( result.current.hookResponse.getTaskMetadata( "evergreen_ubuntu1604_dist_d4cf298cf0b2536fb3bff875775b93a9ceafb75c_21_09_02_14_20_04" @@ -87,25 +84,24 @@ describe("useTestResults", () => { expect(result.current.historyTable.getItem(2)).toMatchObject({ type: rowType.COMMIT, }); - await waitForNextUpdate(); - const response = result.current.hookResponse.getTaskMetadata( - "evergreen_ubuntu1604_dist_d4cf298cf0b2536fb3bff875775b93a9ceafb75c_21_09_02_14_20_04" - ); - expect(response).toMatchObject({ - inactive: false, - label: "", - failingTests: ["TestJiraIntegration"], - loading: false, + await waitFor(() => { + expect( + result.current.hookResponse.getTaskMetadata( + "evergreen_ubuntu1604_dist_d4cf298cf0b2536fb3bff875775b93a9ceafb75c_21_09_02_14_20_04" + ) + ).toMatchObject({ + inactive: false, + label: "", + failingTests: ["TestJiraIntegration"], + loading: false, + }); }); }); it("should return all matching test results when there are matching filters applied and the row is a commit", async () => { - const { result, waitForNextUpdate } = renderHook( - () => useMergedTestHook(1), - { - wrapper: ({ children }) => ProviderWrapper({ children, mocks }), - } - ); + const { result } = renderHook(() => useMergedTestHook(1), { + wrapper: ({ children }) => ProviderWrapper({ children, mocks }), + }); expect( result.current.hookResponse.getTaskMetadata( "evergreen_ubuntu1604_dist_d4cf298cf0b2536fb3bff875775b93a9ceafb75c_21_09_02_14_20_04" @@ -128,26 +124,24 @@ describe("useTestResults", () => { { testName: "TestJiraIntegration", testStatus: TestStatus.Failed }, ]); }); - await waitForNextUpdate(); - expect( - result.current.hookResponse.getTaskMetadata( - "evergreen_ubuntu1604_dist_d4cf298cf0b2536fb3bff875775b93a9ceafb75c_21_09_02_14_20_04" - ) - ).toMatchObject({ - inactive: false, - label: "1 / 1 Failing Tests", - failingTests: ["TestJiraIntegration"], - loading: false, + await waitFor(() => { + expect( + result.current.hookResponse.getTaskMetadata( + "evergreen_ubuntu1604_dist_d4cf298cf0b2536fb3bff875775b93a9ceafb75c_21_09_02_14_20_04" + ) + ).toMatchObject({ + inactive: false, + label: "1 / 1 Failing Tests", + failingTests: ["TestJiraIntegration"], + loading: false, + }); }); }); it("should not return matching test results when there are non matching filters applied and the row is a commit", async () => { - const { result, waitForNextUpdate } = renderHook( - () => useMergedTestHook(1), - { - wrapper: ({ children }) => ProviderWrapper({ children, mocks }), - } - ); + const { result } = renderHook(() => useMergedTestHook(1), { + wrapper: ({ children }) => ProviderWrapper({ children, mocks }), + }); expect( result.current.hookResponse.getTaskMetadata( "evergreen_ubuntu1604_dist_d4cf298cf0b2536fb3bff875775b93a9ceafb75c_21_09_02_14_20_04" @@ -169,15 +163,16 @@ describe("useTestResults", () => { { testName: "NotARealTest", testStatus: TestStatus.Failed }, ]); }); - await waitForNextUpdate(); - expect( - result.current.hookResponse.getTaskMetadata( - "evergreen_ubuntu1604_dist_d4cf298cf0b2536fb3bff875775b93a9ceafb75c_21_09_02_14_20_04" - ) - ).toMatchObject({ - inactive: true, - label: "0 / 1 Failing Tests", - failingTests: [], + await waitFor(() => { + expect( + result.current.hookResponse.getTaskMetadata( + "evergreen_ubuntu1604_dist_d4cf298cf0b2536fb3bff875775b93a9ceafb75c_21_09_02_14_20_04" + ) + ).toMatchObject({ + inactive: true, + label: "0 / 1 Failing Tests", + failingTests: [], + }); }); }); }); diff --git a/src/components/MetadataCard.tsx b/src/components/MetadataCard.tsx index 30868ff5eb..f6b98a96cf 100644 --- a/src/components/MetadataCard.tsx +++ b/src/components/MetadataCard.tsx @@ -32,10 +32,10 @@ export const MetadataCard: React.FC = ({ export const MetadataTitle: React.FC<{ children: React.ReactNode }> = ({ children, }) => ( - <> +
{children} - +
); interface ItemProps { diff --git a/src/components/PageSizeSelector/PageSizeSelector.test.tsx b/src/components/PageSizeSelector/PageSizeSelector.test.tsx index 5e0844c2fb..8b157d2602 100644 --- a/src/components/PageSizeSelector/PageSizeSelector.test.tsx +++ b/src/components/PageSizeSelector/PageSizeSelector.test.tsx @@ -1,8 +1,9 @@ -import { render, screen, userEvent, waitFor } from "test_utils"; +import { render, screen, userEvent } from "test_utils"; import PageSizeSelector from "."; describe("pageSizeSelector", () => { it("selecting page size should call onChange prop", async () => { + const user = userEvent.setup(); const onChange = jest.fn(); render( { onChange={onChange} /> ); - userEvent.click(screen.queryByText("10 / page")); - await waitFor(() => { - expect(screen.queryByText("20 / page")).toBeVisible(); - }); - userEvent.click(screen.queryByText("20 / page")); + await user.click(screen.getByRole("button", { name: "10 / page" })); + expect(screen.queryByText("20 / page")).toBeVisible(); + await user.click(screen.queryByText("20 / page")); expect(onChange).toHaveBeenCalledWith(20); }); }); diff --git a/src/components/Pagination/Pagination.test.tsx b/src/components/Pagination/Pagination.test.tsx index 534c73084f..cc7e22b6d0 100644 --- a/src/components/Pagination/Pagination.test.tsx +++ b/src/components/Pagination/Pagination.test.tsx @@ -1,4 +1,4 @@ -import { renderWithRouterMatch, screen } from "test_utils"; +import { renderWithRouterMatch, screen, userEvent } from "test_utils"; import Pagination from "."; describe("pagination", () => { @@ -34,26 +34,29 @@ describe("pagination", () => { "true" ); }); - it("paginating forward should update the url with the new page number by default", () => { + it("paginating forward should update the url with the new page number by default", async () => { + const user = userEvent.setup(); const { router } = renderWithRouterMatch( ); expect(router.state.location.search).toBe(""); - screen.getByDataCy("next-page-button").click(); + await user.click(screen.getByDataCy("next-page-button")); expect(router.state.location.search).toBe("?page=1"); }); - it("paginating backward should update the url with the new page number by default", () => { + it("paginating backward should update the url with the new page number by default", async () => { + const user = userEvent.setup(); const { router } = renderWithRouterMatch( ); expect(router.state.location.search).toBe(""); - screen.getByDataCy("prev-page-button").click(); + await user.click(screen.getByDataCy("prev-page-button")); expect(router.state.location.search).toBe("?page=0"); }); - it("should call the onChange callback when the page changes", () => { + it("should call the onChange callback when the page changes", async () => { + const user = userEvent.setup(); const onChange = jest.fn(); renderWithRouterMatch( { onChange={onChange} /> ); - screen.getByDataCy("next-page-button").click(); + await user.click(screen.getByDataCy("next-page-button")); expect(onChange).toHaveBeenCalledWith(1); }); it("should disable pagination if there is only one page", () => { diff --git a/src/components/Popconfirm/Popconfirm.test.tsx b/src/components/Popconfirm/Popconfirm.test.tsx index 11a76fb85d..4c6a3a7b51 100644 --- a/src/components/Popconfirm/Popconfirm.test.tsx +++ b/src/components/Popconfirm/Popconfirm.test.tsx @@ -1,9 +1,4 @@ -import { - renderWithRouterMatch as render, - screen, - userEvent, - waitFor, -} from "test_utils"; +import { renderWithRouterMatch as render, screen, userEvent } from "test_utils"; import Popconfirm from "."; describe("controlled popconfirm", () => { @@ -18,7 +13,8 @@ describe("controlled popconfirm", () => { expect(screen.getByRole("button", { name: "Cancel" })).toBeInTheDocument(); }); - it("pressing the Confirm button calls the onConfirm callback and closes the popconfirm", () => { + it("pressing the Confirm button calls the onConfirm callback and closes the popconfirm", async () => { + const user = userEvent.setup(); const onConfirm = jest.fn(); const setOpen = jest.fn(); render( @@ -26,13 +22,14 @@ describe("controlled popconfirm", () => {
hello
); - userEvent.click(screen.getByRole("button", { name: "Yes" })); + await user.click(screen.getByRole("button", { name: "Yes" })); expect(onConfirm).toHaveBeenCalledTimes(1); expect(setOpen).toHaveBeenCalledTimes(1); expect(setOpen).toHaveBeenCalledWith(false); }); - it("pressing the Cancel button calls the onClose callback and closes the popconfirm", () => { + it("pressing the Cancel button calls the onClose callback and closes the popconfirm", async () => { + const user = userEvent.setup(); const onClose = jest.fn(); const setOpen = jest.fn(); render( @@ -40,7 +37,7 @@ describe("controlled popconfirm", () => {
hello
); - userEvent.click(screen.getByRole("button", { name: "Cancel" })); + await user.click(screen.getByRole("button", { name: "Cancel" })); expect(onClose).toHaveBeenCalledTimes(1); expect(setOpen).toHaveBeenCalledTimes(1); expect(setOpen).toHaveBeenCalledWith(false); @@ -61,6 +58,7 @@ describe("controlled popconfirm", () => { describe("uncontrolled popconfirm", () => { it("uses a trigger to open and close the component", async () => { + const user = userEvent.setup(); const onClose = jest.fn(); render( {
hello
); - userEvent.click(screen.getByRole("button", { name: "Open" })); - await waitFor(() => { - expect(screen.getByText("hello")).toBeVisible(); - }); - userEvent.click(screen.getByRole("button", { name: "Open" })); + await user.click(screen.getByRole("button", { name: "Open" })); + expect(screen.getByText("hello")).toBeVisible(); + await user.click(screen.getByRole("button", { name: "Open" })); expect(onClose).toHaveBeenCalledTimes(1); expect(screen.getByText("hello")).not.toBeVisible(); }); diff --git a/src/components/ProjectSelect/ProjectSelect.test.tsx b/src/components/ProjectSelect/ProjectSelect.test.tsx index c8716dca94..bd83b7424e 100644 --- a/src/components/ProjectSelect/ProjectSelect.test.tsx +++ b/src/components/ProjectSelect/ProjectSelect.test.tsx @@ -35,6 +35,7 @@ describe("projectSelect", () => { }); it("should narrow down search results when filtering on projects", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( { expect(screen.getByDataCy("project-select")).toBeInTheDocument(); }); expect(screen.queryByDataCy("project-select-options")).toBeNull(); - userEvent.click(screen.queryByDataCy("project-select")); + await user.click(screen.queryByDataCy("project-select")); expect(screen.getByDataCy("project-select-options")).toBeInTheDocument(); let options = await screen.findAllByDataCy("project-display-name"); expect(options).toHaveLength(6); - userEvent.type( + await user.type( screen.queryByDataCy("project-select-search-input"), "logkeeper" ); @@ -63,6 +64,7 @@ describe("projectSelect", () => { }); it("should be possible to search for projects by a repo name, which should NOT be clickable", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( { expect(screen.getByDataCy("project-select")).toBeInTheDocument(); }); expect(screen.queryByDataCy("project-select-options")).toBeNull(); - userEvent.click(screen.queryByDataCy("project-select")); + await user.click(screen.queryByDataCy("project-select")); expect(screen.getByDataCy("project-select-options")).toBeInTheDocument(); - userEvent.type( + await user.type( screen.queryByDataCy("project-select-search-input"), "aaa/totally-different-name" ); @@ -113,6 +115,7 @@ describe("projectSelect", () => { }); it("should narrow down search results when filtering on projects", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( { expect(screen.getByDataCy("project-select")).toBeInTheDocument(); }); expect(screen.queryByDataCy("project-select-options")).toBeNull(); - userEvent.click(screen.queryByDataCy("project-select")); + await user.click(screen.queryByDataCy("project-select")); expect(screen.getByDataCy("project-select-options")).toBeInTheDocument(); let options = await screen.findAllByDataCy("project-display-name"); expect(options).toHaveLength(5); - userEvent.type( + await user.type( screen.queryByDataCy("project-select-search-input"), "evergreen" ); @@ -142,6 +145,7 @@ describe("projectSelect", () => { }); it("should be possible to search for projects by a repo name, which should be clickable", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( { expect(screen.getByDataCy("project-select")).toBeInTheDocument(); }); expect(screen.queryByDataCy("project-select-options")).toBeNull(); - userEvent.click(screen.queryByDataCy("project-select")); + await user.click(screen.queryByDataCy("project-select")); expect(screen.getByDataCy("project-select-options")).toBeInTheDocument(); - userEvent.type( + await user.type( screen.queryByDataCy("project-select-search-input"), "aaa/totally-different-name" ); @@ -175,6 +179,7 @@ describe("projectSelect", () => { }); it("shows favorited projects twice", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( { expect(screen.getByDataCy("project-select")).toBeInTheDocument(); }); expect(screen.queryByDataCy("project-select-options")).toBeNull(); - userEvent.click(screen.queryByDataCy("project-select")); + await user.click(screen.queryByDataCy("project-select")); expect(screen.getByDataCy("project-select-options")).toBeInTheDocument(); // Favorited projects should appear twice. expect(screen.getAllByText("logkeeper")).toHaveLength(2); }); it("shows disabled projects at the bottom of the list", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( { expect(screen.getByDataCy("project-select")).toBeInTheDocument(); }); expect(screen.queryByDataCy("project-select-options")).toBeNull(); - userEvent.click(screen.queryByDataCy("project-select")); + await user.click(screen.queryByDataCy("project-select")); expect(screen.getByDataCy("project-select-options")).toBeInTheDocument(); const options = await screen.findAllByDataCy("project-display-name"); @@ -223,6 +229,7 @@ describe("projectSelect", () => { }); it("does not show a heading for disabled projects when all projects are enabled", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( { expect(screen.getByDataCy("project-select")).toBeInTheDocument(); }); expect(screen.queryByDataCy("project-select-options")).toBeNull(); - userEvent.click(screen.queryByDataCy("project-select")); + await user.click(screen.queryByDataCy("project-select")); expect(screen.getByDataCy("project-select-options")).toBeInTheDocument(); const options = await screen.findAllByDataCy("project-display-name"); expect(options).toHaveLength(1); diff --git a/src/components/SearchableDropdown/SearchableDropdown.test.tsx b/src/components/SearchableDropdown/SearchableDropdown.test.tsx index 8f05cb517e..b0dac9c257 100644 --- a/src/components/SearchableDropdown/SearchableDropdown.test.tsx +++ b/src/components/SearchableDropdown/SearchableDropdown.test.tsx @@ -7,52 +7,51 @@ const RenderSearchableDropdown = ( describe("searchableDropdown", () => { it("sets the label to what ever the current value is", () => { - const onChange = jest.fn(); render( RenderSearchableDropdown({ value: "evergreen", - onChange, + onChange: jest.fn(), options: ["evergreen", "spruce"], }) ); expect(screen.getByText("evergreen")).toBeInTheDocument(); }); - it("should toggle dropdown when clicking on it", () => { - const onChange = jest.fn(); + it("should toggle dropdown when clicking on it", async () => { + const user = userEvent.setup(); render( RenderSearchableDropdown({ value: "evergreen", - onChange, + onChange: jest.fn(), options: ["evergreen", "spruce"], }) ); expect( screen.queryByDataCy("searchable-dropdown-options") ).not.toBeInTheDocument(); - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect( screen.getByDataCy("searchable-dropdown-options") ).toBeInTheDocument(); - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect( screen.queryByDataCy("searchable-dropdown-options") ).not.toBeInTheDocument(); }); - it("should narrow down search results when filtering", () => { - const onChange = jest.fn(); + it("should narrow down search results when filtering", async () => { + const user = userEvent.setup(); render( RenderSearchableDropdown({ value: "evergreen", - onChange, + onChange: jest.fn(), options: ["evergreen", "spruce"], }) ); expect( screen.queryByDataCy("searchable-dropdown-options") ).not.toBeInTheDocument(); - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect( screen.getByDataCy("searchable-dropdown-options") ).toBeInTheDocument(); @@ -62,7 +61,7 @@ describe("searchableDropdown", () => { expect(screen.queryAllByDataCy("searchable-dropdown-option")).toHaveLength( 2 ); - userEvent.type( + await user.type( screen.queryByDataCy("searchable-dropdown-search-input"), "spru" ); @@ -71,31 +70,31 @@ describe("searchableDropdown", () => { ); }); - it("should reset the search input and options after SearchableDropdown closes", () => { - const onChange = jest.fn(); + it("should reset the search input and options after SearchableDropdown closes", async () => { + const user = userEvent.setup(); render( RenderSearchableDropdown({ value: "evergreen", - onChange, + onChange: jest.fn(), options: ["evergreen", "spruce"], }) ); // use text input to filter and click on document body (which closes the dropdown). - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect(screen.queryAllByDataCy("searchable-dropdown-option")).toHaveLength( 2 ); - userEvent.type( + await user.type( screen.queryByDataCy("searchable-dropdown-search-input"), "spru" ); expect(screen.queryAllByDataCy("searchable-dropdown-option")).toHaveLength( 1 ); - userEvent.click(screen.queryByText("spruce")); + await user.click(screen.queryByText("spruce")); // when reopening the dropdown, the text input should be cleared and all options should be visible. - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect(screen.queryAllByDataCy("searchable-dropdown-option")).toHaveLength( 2 ); @@ -104,25 +103,25 @@ describe("searchableDropdown", () => { ).toHaveValue(""); }); - it("should use custom search function when passed in", () => { - const onChange = jest.fn(); + it("should use custom search function when passed in", async () => { + const user = userEvent.setup(); const searchFunc = jest.fn((options, match) => options.filter((o) => o === match) ); render( RenderSearchableDropdown({ value: ["evergreen"], - onChange, + onChange: jest.fn(), options: ["evergreen", "spruce"], searchFunc, }) ); - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect( screen.getByDataCy("searchable-dropdown-search-input") ).toBeInTheDocument(); - userEvent.type( + await user.type( screen.queryByDataCy("searchable-dropdown-search-input"), "spruce" ); @@ -134,7 +133,8 @@ describe("searchableDropdown", () => { }); describe("when multiselect == false", () => { - it("should call onChange when clicking on an option and should close the option list", () => { + it("should call onChange when clicking on an option and should close the option list", async () => { + const user = userEvent.setup(); const onChange = jest.fn(); const { rerender } = render( RenderSearchableDropdown({ @@ -146,11 +146,11 @@ describe("searchableDropdown", () => { expect( screen.queryByDataCy("searchable-dropdown-options") ).not.toBeInTheDocument(); - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect( screen.getByDataCy("searchable-dropdown-options") ).toBeInTheDocument(); - userEvent.click(screen.queryByText("spruce")); + await user.click(screen.queryByText("spruce")); expect(onChange).toHaveBeenCalledWith("spruce"); expect( screen.queryByDataCy("searchable-dropdown-options") @@ -166,31 +166,31 @@ describe("searchableDropdown", () => { expect(screen.getByText("spruce")).toBeInTheDocument(); }); - it("should reset the search input and options after user selects an option", () => { - const onChange = jest.fn(); + it("should reset the search input and options after user selects an option", async () => { + const user = userEvent.setup(); render( RenderSearchableDropdown({ value: "evergreen", - onChange, + onChange: jest.fn(), options: ["evergreen", "spruce"], }) ); // use text input to filter and select an option. - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect( screen.queryAllByDataCy("searchable-dropdown-option") ).toHaveLength(2); - userEvent.type( + await user.type( screen.queryByDataCy("searchable-dropdown-search-input"), "spru" ); expect( screen.queryAllByDataCy("searchable-dropdown-option") ).toHaveLength(1); - userEvent.click(screen.queryByText("spruce")); + await user.click(screen.queryByText("spruce")); // when reopening the dropdown, the text input should be cleared and all options should be visible. - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect( screen.queryAllByDataCy("searchable-dropdown-option") ).toHaveLength(2); @@ -199,7 +199,8 @@ describe("searchableDropdown", () => { ).toHaveValue(""); }); - it("does not show checkmark next to the selected option", () => { + it("does not show checkmark next to the selected option", async () => { + const user = userEvent.setup(); render( RenderSearchableDropdown({ value: "evergreen", @@ -207,7 +208,7 @@ describe("searchableDropdown", () => { options: ["evergreen", "spruce"], }) ); - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect( screen.queryAllByDataCy("searchable-dropdown-option") ).toHaveLength(2); @@ -216,7 +217,8 @@ describe("searchableDropdown", () => { }); describe("when multiselect == true", () => { - it("should call onChange when clicking on multiple options and shouldn't close the dropdown", () => { + it("should call onChange when clicking on multiple options and shouldn't close the dropdown", async () => { + const user = userEvent.setup(); const onChange = jest.fn(); const { rerender } = render( RenderSearchableDropdown({ @@ -229,11 +231,11 @@ describe("searchableDropdown", () => { expect( screen.queryByDataCy("searchable-dropdown-options") ).not.toBeInTheDocument(); - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect( screen.getByDataCy("searchable-dropdown-options") ).toBeInTheDocument(); - userEvent.click(screen.queryByText("spruce")); + await user.click(screen.queryByText("spruce")); expect(onChange).toHaveBeenCalledWith(["spruce"]); rerender( @@ -256,33 +258,33 @@ describe("searchableDropdown", () => { allowMultiSelect: true, }) ); - userEvent.click(screen.queryByText("evergreen")); + await user.click(screen.queryByText("evergreen")); expect(onChange).toHaveBeenCalledWith(["spruce", "evergreen"]); }); - it("should NOT reset the search input and options after user selects an option", () => { - const onChange = jest.fn(); + it("should NOT reset the search input and options after user selects an option", async () => { + const user = userEvent.setup(); render( RenderSearchableDropdown({ value: "evergreen", - onChange, + onChange: jest.fn(), options: ["evergreen", "spruce", "sandbox"], allowMultiSelect: true, }) ); // use text input to filter and select an option. - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect( screen.queryAllByDataCy("searchable-dropdown-option") ).toHaveLength(3); - userEvent.type( + await user.type( screen.queryByDataCy("searchable-dropdown-search-input"), "s" ); expect( screen.queryAllByDataCy("searchable-dropdown-option") ).toHaveLength(2); - userEvent.click(screen.queryByText("spruce")); + await user.click(screen.queryByText("spruce")); // the dropdown should not be closed and the search state should not be reset. expect( @@ -293,7 +295,8 @@ describe("searchableDropdown", () => { ).toHaveLength(2); }); - it("shows checkmark next to the selected option", () => { + it("shows checkmark next to the selected option", async () => { + const user = userEvent.setup(); render( RenderSearchableDropdown({ value: "evergreen", @@ -302,7 +305,7 @@ describe("searchableDropdown", () => { allowMultiSelect: true, }) ); - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect( screen.queryAllByDataCy("searchable-dropdown-option") ).toHaveLength(2); @@ -311,12 +314,12 @@ describe("searchableDropdown", () => { }); describe("when using custom render options", () => { - it("should render custom options", () => { - const onChange = jest.fn(); + it("should render custom options", async () => { + const user = userEvent.setup(); render( RenderSearchableDropdown({ value: "evergreen", - onChange, + onChange: jest.fn(), options: [ { label: "Evergreen", @@ -338,14 +341,15 @@ describe("searchableDropdown", () => { ), }) ); - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect(screen.getByText("Evergreen")).toBeInTheDocument(); expect(screen.getByText("Spruce")).toBeInTheDocument(); expect(screen.queryByText("Evergreen")).toBeInstanceOf(HTMLButtonElement); expect(screen.queryByText("Spruce")).toBeInstanceOf(HTMLButtonElement); }); - it("should be able to click on custom elements", () => { + it("should be able to click on custom elements", async () => { + const user = userEvent.setup(); const onChange = jest.fn(); render( RenderSearchableDropdown({ @@ -372,19 +376,18 @@ describe("searchableDropdown", () => { ), }) ); - userEvent.click(screen.queryByDataCy("searchable-dropdown")); + await user.click(screen.queryByDataCy("searchable-dropdown")); expect(screen.getByText("Spruce")).toBeInTheDocument(); - userEvent.click(screen.queryByText("Spruce")); + await user.click(screen.queryByText("Spruce")); expect(onChange).toHaveBeenCalledWith("spruce"); }); it("should render a custom button", () => { - const onChange = jest.fn(); render( RenderSearchableDropdown({ value: "evergreen", - onChange, + onChange: jest.fn(), options: ["evergreen", "spruce"], buttonRenderer: (option: string) => ( {option} diff --git a/src/components/SetPriority/SetPriority.test.tsx b/src/components/SetPriority/SetPriority.test.tsx index 85e5bcf7e6..c82b815a40 100644 --- a/src/components/SetPriority/SetPriority.test.tsx +++ b/src/components/SetPriority/SetPriority.test.tsx @@ -14,6 +14,7 @@ import SetPriority from "."; describe("setPriority", () => { describe("patch priority", () => { it("shows default message", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( @@ -21,18 +22,17 @@ describe("setPriority", () => { ); renderWithRouterMatch(); - userEvent.click(screen.queryByDataCy("prioritize-patch")); - await waitFor(() => { - expect( - screen.queryByDataCy("set-patch-priority-popconfirm") - ).toBeVisible(); - }); + await user.click(screen.queryByDataCy("prioritize-patch")); + expect( + screen.queryByDataCy("set-patch-priority-popconfirm") + ).toBeVisible(); expect(screen.queryByDataCy("priority-default-message")).toBeVisible(); - userEvent.type(screen.queryByDataCy("patch-priority-input"), "9"); + await user.type(screen.queryByDataCy("patch-priority-input"), "9"); expect(screen.queryByDataCy("priority-default-message")).toBeVisible(); }); it("shows warning message", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( @@ -40,18 +40,17 @@ describe("setPriority", () => { ); renderWithRouterMatch(); - userEvent.click(screen.queryByDataCy("prioritize-patch")); - await waitFor(() => { - expect( - screen.queryByDataCy("set-patch-priority-popconfirm") - ).toBeVisible(); - }); + await user.click(screen.queryByDataCy("prioritize-patch")); + expect( + screen.queryByDataCy("set-patch-priority-popconfirm") + ).toBeVisible(); expect(screen.queryByDataCy("priority-warning-message")).toBeNull(); - userEvent.type(screen.queryByDataCy("patch-priority-input"), "99"); + await user.type(screen.queryByDataCy("patch-priority-input"), "99"); expect(screen.queryByDataCy("priority-warning-message")).toBeVisible(); }); it("shows admin message", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( @@ -59,18 +58,17 @@ describe("setPriority", () => { ); renderWithRouterMatch(); - userEvent.click(screen.queryByDataCy("prioritize-patch")); - await waitFor(() => { - expect( - screen.queryByDataCy("set-patch-priority-popconfirm") - ).toBeVisible(); - }); + await user.click(screen.queryByDataCy("prioritize-patch")); + expect( + screen.queryByDataCy("set-patch-priority-popconfirm") + ).toBeVisible(); expect(screen.queryByDataCy("priority-admin-message")).toBeNull(); - userEvent.type(screen.queryByDataCy("patch-priority-input"), "999"); + await user.type(screen.queryByDataCy("patch-priority-input"), "999"); expect(screen.queryByDataCy("priority-admin-message")).toBeVisible(); }); it("successfully sets priority", async () => { + const user = userEvent.setup(); const { Component, dispatchToast } = RenderFakeToastContext( @@ -78,22 +76,19 @@ describe("setPriority", () => { ); renderWithRouterMatch(); - userEvent.click(screen.queryByDataCy("prioritize-patch")); - await waitFor(() => { - expect( - screen.queryByDataCy("set-patch-priority-popconfirm") - ).toBeVisible(); - }); - userEvent.type(screen.queryByDataCy("patch-priority-input"), "99"); - userEvent.click(screen.getByRole("button", { name: "Set" })); - await waitFor(() => - expect(dispatchToast.success).toHaveBeenCalledTimes(1) - ); + await user.click(screen.queryByDataCy("prioritize-patch")); + expect( + screen.queryByDataCy("set-patch-priority-popconfirm") + ).toBeVisible(); + await user.type(screen.queryByDataCy("patch-priority-input"), "99"); + await user.click(screen.getByRole("button", { name: "Set" })); + expect(dispatchToast.success).toHaveBeenCalledTimes(1); }); }); describe("task priority", () => { it("shows correct initial priority", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( @@ -101,16 +96,15 @@ describe("setPriority", () => { ); renderWithRouterMatch(); - userEvent.click(screen.queryByDataCy("prioritize-task")); - await waitFor(() => { - expect( - screen.queryByDataCy("set-task-priority-popconfirm") - ).toBeVisible(); - }); + await user.click(screen.queryByDataCy("prioritize-task")); + expect( + screen.queryByDataCy("set-task-priority-popconfirm") + ).toBeVisible(); expect(screen.queryByDataCy("task-priority-input")).toHaveValue(10); }); it("shows default message", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( @@ -118,18 +112,19 @@ describe("setPriority", () => { ); renderWithRouterMatch(); - userEvent.click(screen.queryByDataCy("prioritize-task")); + await user.click(screen.queryByDataCy("prioritize-task")); await waitFor(() => { expect( screen.queryByDataCy("set-task-priority-popconfirm") ).toBeVisible(); }); expect(screen.queryByDataCy("priority-default-message")).toBeVisible(); - userEvent.type(screen.queryByDataCy("task-priority-input"), "9"); + await user.type(screen.queryByDataCy("task-priority-input"), "9"); expect(screen.queryByDataCy("priority-default-message")).toBeVisible(); }); it("shows warning message", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( @@ -137,18 +132,19 @@ describe("setPriority", () => { ); renderWithRouterMatch(); - userEvent.click(screen.queryByDataCy("prioritize-task")); + await user.click(screen.queryByDataCy("prioritize-task")); await waitFor(() => { expect( screen.queryByDataCy("set-task-priority-popconfirm") ).toBeVisible(); }); expect(screen.queryByDataCy("priority-warning-message")).toBeNull(); - userEvent.type(screen.queryByDataCy("task-priority-input"), "99"); + await user.type(screen.queryByDataCy("task-priority-input"), "99"); expect(screen.queryByDataCy("priority-warning-message")).toBeVisible(); }); it("shows admin message", async () => { + const user = userEvent.setup(); const { Component } = RenderFakeToastContext( @@ -156,18 +152,19 @@ describe("setPriority", () => { ); renderWithRouterMatch(); - userEvent.click(screen.queryByDataCy("prioritize-task")); + await user.click(screen.queryByDataCy("prioritize-task")); await waitFor(() => { expect( screen.queryByDataCy("set-task-priority-popconfirm") ).toBeVisible(); }); expect(screen.queryByDataCy("priority-admin-message")).toBeNull(); - userEvent.type(screen.queryByDataCy("task-priority-input"), "999"); + await user.type(screen.queryByDataCy("task-priority-input"), "999"); expect(screen.queryByDataCy("priority-admin-message")).toBeVisible(); }); it("successfully sets priority", async () => { + const user = userEvent.setup(); const { Component, dispatchToast } = RenderFakeToastContext( @@ -175,14 +172,14 @@ describe("setPriority", () => { ); renderWithRouterMatch(); - userEvent.click(screen.queryByDataCy("prioritize-task")); + await user.click(screen.queryByDataCy("prioritize-task")); await waitFor(() => { expect( screen.queryByDataCy("set-task-priority-popconfirm") ).toBeVisible(); }); - userEvent.type(screen.queryByDataCy("task-priority-input"), "99"); - userEvent.click(screen.getByRole("button", { name: "Set" })); + await user.type(screen.queryByDataCy("task-priority-input"), "99"); + await user.click(screen.getByRole("button", { name: "Set" })); await waitFor(() => expect(dispatchToast.success).toHaveBeenCalledTimes(1) ); diff --git a/src/components/Settings/Context.test.tsx b/src/components/Settings/Context.test.tsx index a6561ed45c..6e256d121c 100644 --- a/src/components/Settings/Context.test.tsx +++ b/src/components/Settings/Context.test.tsx @@ -1,5 +1,5 @@ import { AjvError } from "@rjsf/core"; -import { act, renderHook } from "@testing-library/react-hooks"; +import { act, renderHook, waitFor } from "test_utils"; import { initialData, TestProvider, @@ -52,7 +52,7 @@ describe("useTestContext", () => { }); it("marks the tab as having changes when updateForm is called", async () => { - const { result, waitForNextUpdate } = renderHook(() => useTestContext(), { + const { result } = renderHook(() => useTestContext(), { wrapper: TestProvider, }); @@ -67,15 +67,16 @@ describe("useTestContext", () => { }); }); - await waitForNextUpdate(); - expect(result.current.getTab("foo").hasChanges).toBe(true); + await waitFor(() => { + expect(result.current.getTab("foo").hasChanges).toBe(true); + }); expect(result.current.getTab("foo").hasError).toBe(false); expect(result.current.getTab("bar").hasChanges).toBe(false); expect(result.current.getTab("bar").hasError).toBe(false); }); it("updating the form state with identical data does not unsave the tab", async () => { - const { result, waitForNextUpdate } = renderHook(() => useTestContext(), { + const { result } = renderHook(() => useTestContext(), { wrapper: TestProvider, }); @@ -90,7 +91,6 @@ describe("useTestContext", () => { }); }); - await waitForNextUpdate(); expect(result.current.getTab("foo").hasChanges).toBe(false); }); @@ -120,7 +120,7 @@ describe("useHasUnsavedTab", () => { }); it("returns names of unsaved tabs", async () => { - const { result, waitForNextUpdate } = renderHook( + const { result } = renderHook( () => ({ ...useHasUnsavedTab(), ...useTestContext(), @@ -139,9 +139,10 @@ describe("useHasUnsavedTab", () => { }); }); - await waitForNextUpdate(); + await waitFor(() => { + expect(result.current.hasUnsaved).toBe(true); + }); expect(result.current.unsavedTabs).toStrictEqual(["bar"]); - expect(result.current.hasUnsaved).toBe(true); }); }); diff --git a/src/components/Settings/EventLog/EventDiffTable.tsx b/src/components/Settings/EventLog/EventDiffTable.tsx new file mode 100644 index 0000000000..b9f4b3ee2d --- /dev/null +++ b/src/components/Settings/EventLog/EventDiffTable.tsx @@ -0,0 +1,83 @@ +import styled from "@emotion/styled"; +import Badge, { Variant } from "@leafygreen-ui/badge"; +import { Table, TableHeader, Row, Cell } from "@leafygreen-ui/table"; +import { fontFamilies } from "@leafygreen-ui/tokens"; +import { getEventDiffLines } from "./EventLogDiffs"; +import { Event, EventDiffLine, EventValue } from "./types"; + +type TableProps = { + after: Event["after"]; + before: Event["before"]; +}; + +export const EventDiffTable: React.FC = ({ after, before }) => ( + datum.key} + />, + JSON.stringify(datum.before)} + />, + JSON.stringify(datum.after)} + />, + ]} + > + {({ datum }) => ( + + + {datum.key} + + + {renderEventValue(datum.before)} + + + {renderEventValue(datum.after) === null ? ( + Deleted + ) : ( + {renderEventValue(datum.after)} + )} + + + )} +
+); + +const CellText = styled.span` + font-family: ${fontFamilies.code}; + font-size: 12px; + line-height: 16px; + word-break: break-all; +`; + +const renderEventValue = (value: EventValue): string => { + if (value === null || value === undefined) { + return null; + } + if (typeof value === "boolean") { + return String(value); + } + + if (typeof value === "string") { + return `"${value}"`; + } + + if (typeof value === "number") { + return value; + } + + if (Array.isArray(value)) { + return JSON.stringify(value).replaceAll(",", ",\n"); + } + + return JSON.stringify(value); +}; diff --git a/src/components/Settings/EventLog/EventLog.tsx b/src/components/Settings/EventLog/EventLog.tsx new file mode 100644 index 0000000000..4ab57ae962 --- /dev/null +++ b/src/components/Settings/EventLog/EventLog.tsx @@ -0,0 +1,71 @@ +import styled from "@emotion/styled"; +import Button from "@leafygreen-ui/button"; +import Card from "@leafygreen-ui/card"; +import { Spinner } from "@leafygreen-ui/loading-indicator"; +import { Subtitle } from "@leafygreen-ui/typography"; +import { size } from "constants/tokens"; +import { EventDiffTable } from "./EventDiffTable"; +import { Header } from "./Header"; +import { Event } from "./types"; + +type EventLogProps = { + allEventsFetched: boolean; + eventRenderer?: (event: Event) => React.ReactNode; + events: Event[]; + handleFetchMore: () => void; + loading?: boolean; +}; + +export const EventLog: React.FC = ({ + allEventsFetched, + eventRenderer, + events, + handleFetchMore, + loading, +}) => { + const allEventsFetchedCopy = + events.length > 0 ? "No more events to show." : "No events to show."; + + return ( + + {events.map((event) => { + const { after, before, timestamp, user } = event; + return ( + +
+ {eventRenderer ? ( + eventRenderer(event) + ) : ( + + )} + + ); + })} + {!allEventsFetched && !!events.length && ( + + )} + {allEventsFetched && {allEventsFetchedCopy}} + + ); +}; + +const Container = styled.div` + display: flex; + flex-direction: column; + align-items: center; + width: 150%; +`; + +const EventLogCard = styled(Card)` + width: 100%; + margin-bottom: ${size.l}; + padding: ${size.m}; +`; diff --git a/src/pages/projectSettings/tabs/EventLogTab/EventLogDiffs.test.ts b/src/components/Settings/EventLog/EventLogDiffs.test.ts similarity index 100% rename from src/pages/projectSettings/tabs/EventLogTab/EventLogDiffs.test.ts rename to src/components/Settings/EventLog/EventLogDiffs.test.ts diff --git a/src/pages/projectSettings/tabs/EventLogTab/EventLogDiffs.ts b/src/components/Settings/EventLog/EventLogDiffs.ts similarity index 82% rename from src/pages/projectSettings/tabs/EventLogTab/EventLogDiffs.ts rename to src/components/Settings/EventLog/EventLogDiffs.ts index 8d577aea50..eea711972c 100644 --- a/src/pages/projectSettings/tabs/EventLogTab/EventLogDiffs.ts +++ b/src/components/Settings/EventLog/EventLogDiffs.ts @@ -1,7 +1,6 @@ import { diff } from "deep-object-diff"; -import { ProjectEventSettings } from "gql/generated/types"; -import { Subset } from "types/utils"; import { string } from "utils"; +import { Event, EventDiffLine, EventValue } from "./types"; const { omitTypename } = string; @@ -27,16 +26,9 @@ const formatArrayElements = (eventKey: string): string => const getNestedObject = (nestedObj: object, pathArr: string[]): EventValue => pathArr.reduce((obj, key) => (obj ? obj[key] : undefined), nestedObj); -export type EventValue = boolean | string | Array; -export type EventDiffLine = { - key: string; - before: EventValue; - after: EventValue; -}; - export const getEventDiffLines = ( - before: Subset, - after: Subset + before: Event["before"], + after: Event["after"] ): EventDiffLine[] => { const beforeNoTypename = omitTypename(before); const afterNoTypename = omitTypename(after); diff --git a/src/components/Settings/EventLog/Header.tsx b/src/components/Settings/EventLog/Header.tsx new file mode 100644 index 0000000000..250a986bf3 --- /dev/null +++ b/src/components/Settings/EventLog/Header.tsx @@ -0,0 +1,24 @@ +import styled from "@emotion/styled"; +import { Subtitle } from "@leafygreen-ui/typography"; +import { size } from "constants/tokens"; +import { useDateFormat } from "hooks"; + +interface Props { + timestamp: Date; + user: string; +} + +export const Header: React.FC = ({ timestamp, user }) => { + const getDateCopy = useDateFormat(); + + return ( + + {getDateCopy(timestamp)} +
{user}
+
+ ); +}; + +const StyledHeader = styled.div` + padding-bottom: ${size.s}; +`; diff --git a/src/components/Settings/EventLog/index.ts b/src/components/Settings/EventLog/index.ts new file mode 100644 index 0000000000..c061ae102c --- /dev/null +++ b/src/components/Settings/EventLog/index.ts @@ -0,0 +1,4 @@ +export { EventDiffTable } from "./EventDiffTable"; +export { EventLog } from "./EventLog"; +export { EVENT_LIMIT, useEvents } from "./useEvents"; +export type { Event } from "./types"; diff --git a/src/components/Settings/EventLog/types.ts b/src/components/Settings/EventLog/types.ts new file mode 100644 index 0000000000..820fed79f8 --- /dev/null +++ b/src/components/Settings/EventLog/types.ts @@ -0,0 +1,19 @@ +export type EventValue = + | boolean + | string + | object + | Array; + +export type Event = { + after?: Record; + before?: Record; + data?: Record; + timestamp: Date; + user: string; +}; + +export type EventDiffLine = { + key: string; + before: EventValue; + after: EventValue; +}; diff --git a/src/components/Settings/EventLog/useEvents.ts b/src/components/Settings/EventLog/useEvents.ts new file mode 100644 index 0000000000..19826d05f1 --- /dev/null +++ b/src/components/Settings/EventLog/useEvents.ts @@ -0,0 +1,22 @@ +import { useState } from "react"; + +export const EVENT_LIMIT = 15; + +export const useEvents = (limit: number) => { + const [allEventsFetched, setAllEventsFetched] = useState(false); + const [prevCount, setPrevCount] = useState(0); + + // Hide Load More button when event count < limit is returned, + // or when an additional fetch fails to load more events. + const onCompleted = (count: number) => { + if (count - prevCount < limit) { + setAllEventsFetched(true); + } + }; + + return { + allEventsFetched, + onCompleted, + setPrevCount, + }; +}; diff --git a/src/components/Settings/Form.test.tsx b/src/components/Settings/Form.test.tsx index 86432f3514..7b59e90bf2 100644 --- a/src/components/Settings/Form.test.tsx +++ b/src/components/Settings/Form.test.tsx @@ -40,22 +40,26 @@ describe("context-based form", () => { expect(screen.getByLabelText("Caps Lock Enabled")).toBeChecked(); }); - it("updates the data", () => { + it("updates the data", async () => { + const user = userEvent.setup(); render(, { wrapper: TestProvider, }); - userEvent.click(screen.getByLabelText("Caps Lock Enabled")); - expect(screen.getByLabelText("Caps Lock Enabled")).not.toBeChecked(); + const checkbox = screen.getByRole("checkbox"); + expect(checkbox).toBeChecked(); + await user.click(screen.getByText("Caps Lock Enabled")); + expect(checkbox).not.toBeChecked(); }); - it("applies a validate function that shows an error message", () => { + it("applies a validate function that shows an error message", async () => { + const user = userEvent.setup(); render(, { wrapper: TestProvider, }); - userEvent.clear(screen.getByLabelText("Age")); + await user.clear(screen.getByLabelText("Age")); expect(screen.getByLabelText("Age")).toHaveValue(""); expect(screen.queryByText("Invalid Age!")).not.toBeInTheDocument(); - userEvent.type(screen.getByLabelText("Age"), "30"); + await user.type(screen.getByLabelText("Age"), "30"); expect(screen.getByText("Invalid Age!")).toBeInTheDocument(); }); diff --git a/src/components/Settings/NavigationWarningModal.test.tsx b/src/components/Settings/NavigationWarningModal.test.tsx index 8025de3b64..2eb756f178 100644 --- a/src/components/Settings/NavigationWarningModal.test.tsx +++ b/src/components/Settings/NavigationWarningModal.test.tsx @@ -4,7 +4,7 @@ import { Outlet, RouterProvider, } from "react-router-dom"; -import { act, render, screen, userEvent } from "test_utils"; +import { render, screen, userEvent } from "test_utils"; import { NavigationModalProps, NavigationWarningModal, @@ -44,13 +44,14 @@ const getRouter = ({ shouldBlock, unsavedTabs }: NavigationModalProps) => ); describe("navigation warning", () => { - it("does not warn when navigating and shouldBlock is false", () => { + it("does not warn when navigating and shouldBlock is false", async () => { const router = getRouter({ shouldBlock: false, unsavedTabs: [] }); + const user = userEvent.setup(); render(); expect(router.state.location.pathname).toBe("/"); - userEvent.click(screen.getByRole("link")); + await user.click(screen.getByRole("link")); expect(router.state.location.pathname).toBe("/about"); expect( screen.queryByDataCy("navigation-warning-modal") @@ -58,76 +59,74 @@ describe("navigation warning", () => { expect(screen.queryByRole("heading")).toHaveTextContent("About Page"); }); - it("warns and shows the modal with unsaved pages", () => { + it("warns and shows the modal with unsaved pages", async () => { const router = getRouter({ shouldBlock: true, unsavedTabs: [{ title: "An Unsaved Page", value: "foo" }], }); + const user = userEvent.setup(); render(); expect(router.state.location.pathname).toBe("/"); - userEvent.click(screen.getByRole("link")); + await user.click(screen.getByRole("link")); expect(router.state.location.pathname).toBe("/"); expect(screen.getByDataCy("navigation-warning-modal")).toBeInTheDocument(); expect(screen.getByText("An Unsaved Page")).toBeInTheDocument(); }); - it("warns and shows the modal with unsaved pages when a function is provided to shouldBlock", () => { + it("warns and shows the modal with unsaved pages when a function is provided to shouldBlock", async () => { const router = getRouter({ shouldBlock: () => true, unsavedTabs: [{ title: "An Unsaved Page", value: "foo" }], }); + const user = userEvent.setup(); render(); expect(router.state.location.pathname).toBe("/"); - userEvent.click(screen.getByRole("link")); + await user.click(screen.getByRole("link")); expect(router.state.location.pathname).toBe("/"); expect(screen.getByDataCy("navigation-warning-modal")).toBeInTheDocument(); expect(screen.getByText("An Unsaved Page")).toBeInTheDocument(); }); - it("navigates to the next page when 'Leave' button is clicked", () => { + it("navigates to the next page when 'Leave' button is clicked", async () => { const router = getRouter({ shouldBlock: true, unsavedTabs: [{ title: "An Unsaved Page", value: "foo" }], }); + const user = userEvent.setup(); render(); expect(router.state.location.pathname).toBe("/"); - userEvent.click(screen.getByRole("link")); + await user.click(screen.getByRole("link")); expect(router.state.location.pathname).toBe("/"); expect(screen.getByDataCy("navigation-warning-modal")).toBeInTheDocument(); expect(screen.getByText("An Unsaved Page")).toBeInTheDocument(); - // eslint-disable-next-line testing-library/no-unnecessary-act - act(() => { - userEvent.click(screen.getByRole("button", { name: "Leave" })); - }); + await user.click(screen.getByRole("button", { name: "Leave" })); expect(router.state.location.pathname).toBe("/about"); expect(screen.queryByRole("heading")).toHaveTextContent("About Page"); }); - it("remains on the initial page when 'Cancel' button is clicked", () => { + it("remains on the initial page when 'Cancel' button is clicked", async () => { const router = getRouter({ shouldBlock: true, unsavedTabs: [{ title: "An Unsaved Page", value: "foo" }], }); + const user = userEvent.setup(); render(); expect(router.state.location.pathname).toBe("/"); - userEvent.click(screen.getByRole("link")); + await user.click(screen.getByRole("link")); expect(router.state.location.pathname).toBe("/"); expect(screen.getByDataCy("navigation-warning-modal")).toBeInTheDocument(); expect(screen.getByText("An Unsaved Page")).toBeInTheDocument(); - // eslint-disable-next-line testing-library/no-unnecessary-act - act(() => { - userEvent.click(screen.getByRole("button", { name: "Cancel" })); - }); + await user.click(screen.getByRole("button", { name: "Cancel" })); expect(router.state.location.pathname).toBe("/"); expect(screen.queryByRole("heading")).toHaveTextContent("Home Page"); }); diff --git a/src/components/SettingsCard.tsx b/src/components/SettingsCard.tsx index 6bf0f0bfc3..a6596f7630 100644 --- a/src/components/SettingsCard.tsx +++ b/src/components/SettingsCard.tsx @@ -12,7 +12,5 @@ export const formComponentSpacingCSS = "margin-bottom: 48px;"; export const SettingsCard = styled(Card)` padding: ${size.m}; - :not(:last-of-type) { - ${formComponentSpacingCSS} - } + ${formComponentSpacingCSS} `; diff --git a/src/components/SpruceForm/FieldTemplates/ObjectFieldTemplates/ObjectFieldTemplates.test.tsx b/src/components/SpruceForm/FieldTemplates/ObjectFieldTemplates/ObjectFieldTemplates.test.tsx index 0e0725435b..6f4b710546 100644 --- a/src/components/SpruceForm/FieldTemplates/ObjectFieldTemplates/ObjectFieldTemplates.test.tsx +++ b/src/components/SpruceForm/FieldTemplates/ObjectFieldTemplates/ObjectFieldTemplates.test.tsx @@ -46,12 +46,11 @@ describe("objectFieldTemplates", () => { expect(screen.getByDataCy("name")).toBeInTheDocument(); }); it("renders all fields", () => { - const onChange = jest.fn(); render( ); @@ -59,11 +58,13 @@ describe("objectFieldTemplates", () => { expect(screen.getByDataCy("age")).toBeInTheDocument(); }); - it("calls onChange when a field is changed", () => { + it("calls onChange when a field is changed", async () => { let data; const onChange = jest.fn(({ formData }) => { data = formData; }); + + const user = userEvent.setup(); render( { uiSchema={uiSchema} /> ); - userEvent.type(screen.getByDataCy("name"), "Bruce Lee"); - userEvent.type(screen.getByDataCy("age"), "32"); - + await user.type(screen.getByDataCy("name"), "Bruce Lee"); + await user.type(screen.getByDataCy("age"), "32"); expect(data).toStrictEqual({ person: { name: "Bruce Lee", age: 32 } }); }); }); @@ -92,35 +92,35 @@ describe("objectFieldTemplates", () => { }, }; it("applies data-cy attributes", () => { - const onChange = jest.fn(); render( ); expect(screen.getByDataCy("name")).toBeInTheDocument(); }); it("renders all fields in a card", () => { - const onChange = jest.fn(); render( ); expect(screen.getByDataCy("name")).toBeInTheDocument(); expect(screen.getByDataCy("age")).toBeInTheDocument(); }); - it("calls onChange when a field is changed", () => { + it("calls onChange when a field is changed", async () => { let data; const onChange = jest.fn(({ formData }) => { data = formData; }); + + const user = userEvent.setup(); render( { uiSchema={uiSchema} /> ); - userEvent.type(screen.getByDataCy("name"), "Bruce Lee"); - userEvent.type(screen.getByDataCy("age"), "32"); - + await user.type(screen.getByDataCy("name"), "Bruce Lee"); + await user.type(screen.getByDataCy("age"), "32"); expect(data).toStrictEqual({ person: { name: "Bruce Lee", age: 32 } }); }); }); @@ -148,35 +147,35 @@ describe("objectFieldTemplates", () => { }, }; it("applies data-cy attributes", () => { - const onChange = jest.fn(); render( ); expect(screen.getByDataCy("name")).toBeInTheDocument(); }); it("renders all fields in an accordion", () => { - const onChange = jest.fn(); render( ); expect(screen.getByDataCy("name")).toBeInTheDocument(); expect(screen.getByDataCy("age")).toBeInTheDocument(); }); - it("calls onChange when a field is changed", () => { + it("calls onChange when a field is changed", async () => { let data; const onChange = jest.fn(({ formData }) => { data = formData; }); + + const user = userEvent.setup(); render( { uiSchema={uiSchema} /> ); - userEvent.type(screen.getByDataCy("name"), "Bruce Lee"); - userEvent.type(screen.getByDataCy("age"), "32"); + await user.type(screen.getByDataCy("name"), "Bruce Lee"); + await user.type(screen.getByDataCy("age"), "32"); expect(data).toStrictEqual({ person: { name: "Bruce Lee", age: 32 } }); }); it("accordion is expanded by default", () => { - const onChange = jest.fn(); render( ); @@ -205,12 +203,11 @@ describe("objectFieldTemplates", () => { ).toHaveAttribute("aria-expanded", "true"); }); it("accordion is collapsed by default if defaultOpen is false", () => { - const onChange = jest.fn(); render( { it("should render as expected", () => { - const onChange = jest.fn(); render( @@ -28,6 +27,8 @@ describe("spruce form", () => { const { formData } = x; data = formData; }); + + const user = userEvent.setup(); render( { /> ); - userEvent.clear(screen.queryByDataCy("valid-projects-input")); - userEvent.type(screen.queryByDataCy("valid-projects-input"), "new value"); - userEvent.click(screen.queryByDataCy("add-button")); - await waitFor(() => - expect(screen.queryAllByDataCy("new-user-input")).toHaveLength(2) - ); - userEvent.type(screen.queryAllByDataCy("new-user-input")[0], "new-user"); + await user.clear(screen.queryByDataCy("valid-projects-input")); + await user.type(screen.queryByDataCy("valid-projects-input"), "new value"); + await user.click(screen.queryByDataCy("add-button")); + expect(screen.queryAllByDataCy("new-user-input")).toHaveLength(2); + await user.type(screen.queryAllByDataCy("new-user-input")[0], "new-user"); expect(onChange).toHaveBeenCalled(); // eslint-disable-line jest/prefer-called-with expect(screen.queryByDataCy("valid-projects-input")).toHaveValue( "new value" @@ -60,7 +59,7 @@ describe("spruce form", () => { describe("form elements", () => { describe("text input", () => { describe("invisible errors", () => { - it("should work with validate function", () => { + it("should work with validate function", async () => { let formErrors = {}; const onChange = jest.fn((x) => { const { errors } = x; @@ -68,6 +67,7 @@ describe("spruce form", () => { }); const validate = jest.fn((_formData, err) => err); + const user = userEvent.setup(); const { formData, schema, uiSchema } = textInput(); render( @@ -80,8 +80,8 @@ describe("spruce form", () => { /> ); - userEvent.type(screen.queryByDataCy("text-input"), "new value"); - userEvent.clear(screen.queryByDataCy("text-input")); + await user.type(screen.queryByDataCy("text-input"), "new value"); + await user.clear(screen.queryByDataCy("text-input")); expect(screen.queryByDataCy("text-input")).toHaveValue(""); // Invisible errors should be in the form error state but not visible on the page. @@ -91,12 +91,14 @@ describe("spruce form", () => { }); describe("emptyValue", () => { - it("defaults to '' when not specified", () => { + it("defaults to '' when not specified", async () => { let data = {}; const onChange = jest.fn((x) => { const { formData } = x; data = formData; }); + + const user = userEvent.setup(); const { formData, schema, uiSchema } = textInput(); render( @@ -108,20 +110,22 @@ describe("spruce form", () => { /> ); - userEvent.type(screen.queryByDataCy("text-input"), "new value"); - userEvent.clear(screen.queryByDataCy("text-input")); + await user.type(screen.queryByDataCy("text-input"), "new value"); + await user.clear(screen.queryByDataCy("text-input")); expect(screen.queryByDataCy("text-input")).toHaveValue(""); expect(data).toStrictEqual({ textInput: "", }); }); - it("uses provided value when specified", () => { + it("uses provided value when specified", async () => { let data = {}; const onChange = jest.fn((x) => { const { formData } = x; data = formData; }); + + const user = userEvent.setup(); const { formData, schema, uiSchema } = textInput("myEmptyValue"); render( @@ -133,8 +137,8 @@ describe("spruce form", () => { /> ); - userEvent.type(screen.queryByDataCy("text-input"), "new value"); - userEvent.clear(screen.queryByDataCy("text-input")); + await user.type(screen.queryByDataCy("text-input"), "new value"); + await user.clear(screen.queryByDataCy("text-input")); expect(screen.queryByDataCy("text-input")).toHaveValue( "myEmptyValue" ); @@ -147,7 +151,7 @@ describe("spruce form", () => { describe("text area", () => { describe("invisible errors", () => { - it("should work with validate function", () => { + it("should work with validate function", async () => { let formErrors = {}; const onChange = jest.fn((x) => { const { errors } = x; @@ -155,6 +159,7 @@ describe("spruce form", () => { }); const validate = jest.fn((_formData, err) => err); + const user = userEvent.setup(); const { formData, schema, uiSchema } = textArea(); render( @@ -167,8 +172,8 @@ describe("spruce form", () => { /> ); - userEvent.type(screen.queryByDataCy("text-area"), "new value"); - userEvent.clear(screen.queryByDataCy("text-area")); + await user.type(screen.queryByDataCy("text-area"), "new value"); + await user.clear(screen.queryByDataCy("text-area")); expect(screen.queryByDataCy("text-area")).toHaveValue(""); // Invisible errors should be in the form error state but not visible on the page. @@ -178,12 +183,14 @@ describe("spruce form", () => { }); describe("emptyValue", () => { - it("defaults to '' when not specified", () => { + it("defaults to '' when not specified", async () => { let data = {}; const onChange = jest.fn((x) => { const { formData } = x; data = formData; }); + + const user = userEvent.setup(); const { formData, schema, uiSchema } = textArea(); render( @@ -195,20 +202,22 @@ describe("spruce form", () => { /> ); - userEvent.type(screen.queryByDataCy("text-area"), "new value"); - userEvent.clear(screen.queryByDataCy("text-area")); + await user.type(screen.queryByDataCy("text-area"), "new value"); + await user.clear(screen.queryByDataCy("text-area")); expect(screen.queryByDataCy("text-area")).toHaveValue(""); expect(data).toStrictEqual({ textArea: "", }); }); - it("uses provided value when specified", () => { + it("uses provided value when specified", async () => { let data = {}; const onChange = jest.fn((x) => { const { formData } = x; data = formData; }); + + const user = userEvent.setup(); const { formData, schema, uiSchema } = textArea("myEmptyValue"); render( @@ -220,8 +229,8 @@ describe("spruce form", () => { /> ); - userEvent.type(screen.queryByDataCy("text-area"), "new value"); - userEvent.clear(screen.queryByDataCy("text-area")); + await user.type(screen.queryByDataCy("text-area"), "new value"); + await user.clear(screen.queryByDataCy("text-area")); expect(screen.queryByDataCy("text-area")).toHaveValue("myEmptyValue"); expect(data).toStrictEqual({ textArea: "myEmptyValue", @@ -232,13 +241,12 @@ describe("spruce form", () => { describe("select", () => { it("renders with the specified default selected", () => { - const onChange = jest.fn(); const { formData, schema, uiSchema } = select; render( ); @@ -247,36 +255,36 @@ describe("spruce form", () => { expect(screen.queryByText("Strawberry")).not.toBeInTheDocument(); }); - it("shows three options on click", () => { - const onChange = jest.fn(); + it("shows three options on click", async () => { + const user = userEvent.setup(); const { formData, schema, uiSchema } = select; render( ); - userEvent.click(screen.queryByRole("button")); + await user.click(screen.queryByRole("button")); expect(screen.queryAllByText("Vanilla")).toHaveLength(2); expect(screen.getByText("Chocolate")).toBeInTheDocument(); expect(screen.getByText("Strawberry")).toBeInTheDocument(); }); it("closes the menu and displays the new selected option on click", async () => { - const onChange = jest.fn(); + const user = userEvent.setup(); const { formData, schema, uiSchema } = select; render( ); - userEvent.click(screen.queryByRole("button")); - userEvent.click(screen.queryByText("Chocolate")); + await user.click(screen.getByRole("button")); + await user.click(screen.getByRole("option", { name: "Chocolate" })); await waitFor(() => { expect(screen.queryByText("Vanilla")).not.toBeInTheDocument(); }); @@ -285,17 +293,17 @@ describe("spruce form", () => { }); it("disables options included in enumDisabled", async () => { - const onChange = jest.fn(); + const user = userEvent.setup(); const { formData, schema, uiSchema } = select; render( ); - userEvent.click(screen.queryByRole("button")); + await user.click(screen.queryByRole("button")); // LeafyGreen doesn't label disabled options as such, so instead of checking for a property // ensure that the disabled element is not clickable. @@ -310,47 +318,41 @@ describe("spruce form", () => { describe("radio group", () => { it("renders 3 inputs with the specified default selected", () => { const { formData, schema, uiSchema } = radioGroup; - const onChange = jest.fn(); render( ); - expect(screen.getAllByRole("radio")).toHaveLength(3); expect(screen.getByLabelText("New York")).toBeChecked(); }); it("disables options in enumDisabled", () => { const { formData, schema, uiSchema } = radioGroup; - const onChange = jest.fn(); render( ); - expect(screen.getByLabelText("Connecticut")).toBeDisabled(); }); it("shows option descriptions", () => { const { formData, schema, uiSchema } = radioGroup; - const onChange = jest.fn(); render( ); - expect(screen.getByText("The Garden State")).toBeVisible(); }); }); diff --git a/src/components/SpruceForm/__snapshots__/SpruceForm.stories.storyshot b/src/components/SpruceForm/__snapshots__/SpruceForm.stories.storyshot index b61e2dd5f8..1f00fbec7f 100644 --- a/src/components/SpruceForm/__snapshots__/SpruceForm.stories.storyshot +++ b/src/components/SpruceForm/__snapshots__/SpruceForm.stories.storyshot @@ -9,7 +9,7 @@ exports[`storybook Storyshots components/SpruceForm Example 1 1`] = ` Distro Projects
{ expect(checkbox).toBeChecked(); }); - it("clicking a value selects its option in the tree select", () => { + it("clicking a value selects its option in the tree select", async () => { + const user = userEvent.setup(); const onChange = jest.fn(); render(); expect(screen.getByText("Pass")).toBeInTheDocument(); - userEvent.click(screen.queryByText("Pass")); + await user.click(screen.queryByText("Pass")); expect(onChange).toHaveBeenCalledWith(["pass"]); }); - it("clicking all selects all of the options in the tree select", () => { + it("clicking all selects all of the options in the tree select", async () => { + const user = userEvent.setup(); const onChange = jest.fn(); render(); expect(screen.getByText("All")).toBeInTheDocument(); - userEvent.click(screen.queryByText("All")); + await user.click(screen.queryByText("All")); expect(onChange).toHaveBeenCalledWith([ "all", "pass", @@ -51,7 +53,8 @@ describe("treeSelect", () => { expect(screen.getByText("Fail")).toBeInTheDocument(); }); - it("unchecking a child element should uncheck its parent", () => { + it("unchecking a child element should uncheck its parent", async () => { + const user = userEvent.setup(); let state = ["failing-umbrella", "system-failure", "fail"]; const onChange = jest.fn((update) => { state = update; @@ -62,17 +65,18 @@ describe("treeSelect", () => { expect(screen.queryByLabelText("Failing Umbrella")).toBeChecked(); expect(screen.queryByLabelText("System Failure")).toBeChecked(); expect(screen.queryByLabelText("Fail")).toBeChecked(); - userEvent.click(screen.queryByText("Fail")); + await user.click(screen.queryByText("Fail")); expect(onChange).toHaveBeenCalledWith(["system-failure"]); }); - it("checking a parent element should toggle its children", () => { + it("checking a parent element should toggle its children", async () => { + const user = userEvent.setup(); const onChange = jest.fn(); render( ); expect(screen.getByText("Failing Umbrella")).toBeInTheDocument(); - userEvent.click(screen.queryByText("Failing Umbrella")); + await user.click(screen.queryByText("Failing Umbrella")); expect(onChange).toHaveBeenCalledWith([ "failing-umbrella", "system-failure", diff --git a/src/components/TupleSelect/TupleSelect.test.tsx b/src/components/TupleSelect/TupleSelect.test.tsx index 8210ed77f0..21d6731855 100644 --- a/src/components/TupleSelect/TupleSelect.test.tsx +++ b/src/components/TupleSelect/TupleSelect.test.tsx @@ -35,7 +35,8 @@ describe("tupleSelect", () => { expect(input).toHaveValue(""); }); - it("should clear input when a value is submitted", () => { + it("should clear input when a value is submitted", async () => { + const user = userEvent.setup(); const onSubmit = jest.fn(); const validator = jest.fn((v) => v !== "bad"); const validatorErrorMessage = "Invalid Input"; @@ -50,12 +51,13 @@ describe("tupleSelect", () => { const input = screen.queryByDataCy("tuple-select-input"); expect(input).toHaveValue(""); - userEvent.type(input, "some-filter"); - userEvent.type(input, "{enter}"); + await user.type(input, "some-filter"); + await user.type(input, "{enter}"); expect(input).toHaveValue(""); }); it("should validate the input and prevent submission if it fails validation", async () => { + const user = userEvent.setup(); const onSubmit = jest.fn(); const validator = jest.fn((v) => v !== "bad"); const validatorErrorMessage = "Invalid Input"; @@ -70,14 +72,14 @@ describe("tupleSelect", () => { const input = screen.queryByDataCy("tuple-select-input"); expect(input).toHaveValue(""); - userEvent.type(input, "bad"); + await user.type(input, "bad"); expect(input).toHaveValue("bad"); - userEvent.type(input, "{enter}"); + await user.type(input, "{enter}"); expect(input).toHaveValue("bad"); expect(onSubmit).not.toHaveBeenCalled(); expect(validator).toHaveBeenLastCalledWith("bad"); expect(screen.getByDataCy("tuple-select-warning")).toBeInTheDocument(); - userEvent.hover(screen.queryByDataCy("tuple-select-warning")); + await user.hover(screen.queryByDataCy("tuple-select-warning")); await screen.findByText(validatorErrorMessage); }); }); diff --git a/src/components/TupleSelectWithRegexConditional/TupleSelectWithRegexConditional.test.tsx b/src/components/TupleSelectWithRegexConditional/TupleSelectWithRegexConditional.test.tsx index f6923936bb..ff8a23f7bb 100644 --- a/src/components/TupleSelectWithRegexConditional/TupleSelectWithRegexConditional.test.tsx +++ b/src/components/TupleSelectWithRegexConditional/TupleSelectWithRegexConditional.test.tsx @@ -34,7 +34,8 @@ describe("tupleSelectWithRegexConditional", () => { expect(dropdown).toHaveTextContent("Build Variant"); expect(input).toHaveValue(""); }); - it("should clear input when a value is submitted", () => { + it("should clear input when a value is submitted", async () => { + const user = userEvent.setup(); const onSubmit = jest.fn(); const validator = jest.fn((v) => v !== "bad"); const validatorErrorMessage = "Invalid Input"; @@ -49,12 +50,13 @@ describe("tupleSelectWithRegexConditional", () => { const input = screen.queryByDataCy("tuple-select-input"); expect(input).toHaveValue(""); - userEvent.type(input, "some-filter"); - userEvent.type(input, "{enter}"); + await user.type(input, "some-filter"); + await user.type(input, "{enter}"); expect(input).toHaveValue(""); }); it("should validate the input and prevent submission if it fails validation and input type is set to `regex`", async () => { + const user = userEvent.setup(); const onSubmit = jest.fn(); const validator = jest.fn((v) => v !== "bad"); const validatorErrorMessage = "Invalid Input"; @@ -69,19 +71,20 @@ describe("tupleSelectWithRegexConditional", () => { const input = screen.queryByDataCy("tuple-select-input"); expect(input).toHaveValue(""); - userEvent.type(input, "bad"); + await user.type(input, "bad"); expect(input).toHaveValue("bad"); - userEvent.type(input, "{enter}"); + await user.type(input, "{enter}"); expect(input).toHaveValue("bad"); expect(onSubmit).not.toHaveBeenCalled(); expect(validator).toHaveBeenLastCalledWith("bad"); expect(screen.getByDataCy("tuple-select-warning")).toBeInTheDocument(); - userEvent.hover(screen.queryByDataCy("tuple-select-warning")); + await user.hover(screen.queryByDataCy("tuple-select-warning")); await waitFor(() => { expect(screen.getByText(validatorErrorMessage)).toBeInTheDocument(); }); }); - it("toggling the input type selector to `exact` should escape any regex characters", () => { + it("toggling the input type selector to `exact` should escape any regex characters", async () => { + const user = userEvent.setup(); const onSubmit = jest.fn(); const validator = jest.fn((v) => v !== "bad"); const validatorErrorMessage = "Invalid Input"; @@ -93,20 +96,20 @@ describe("tupleSelectWithRegexConditional", () => { validatorErrorMessage={validatorErrorMessage} /> ); - userEvent.click(screen.getByRole("tab", { name: "EXACT" })); + await user.click(screen.getByRole("tab", { name: "EXACT" })); const input = screen.queryByDataCy("tuple-select-input"); expect(input).toHaveValue(""); - userEvent.type(input, "some-*"); + await user.type(input, "some-*"); expect(input).toHaveValue("some-*"); - userEvent.type(input, "{enter}"); + await user.type(input, "{enter}"); expect(onSubmit).toHaveBeenCalledWith({ category: "build_variant", value: "some\\-\\*", }); - expect(input).toHaveValue(""); }); - it("should not attempt to validate input if using the `exact` input type", () => { + it("should not attempt to validate input if using the `exact` input type", async () => { + const user = userEvent.setup(); const onSubmit = jest.fn(); const validator = jest.fn((v) => v !== "bad"); const validatorErrorMessage = "Invalid Input"; @@ -118,11 +121,11 @@ describe("tupleSelectWithRegexConditional", () => { validatorErrorMessage={validatorErrorMessage} /> ); - userEvent.click(screen.getByRole("tab", { name: "EXACT" })); + await user.click(screen.getByRole("tab", { name: "EXACT" })); const input = screen.queryByDataCy("tuple-select-input"); expect(input).toHaveValue(""); - userEvent.type(input, "some-["); - expect(input).toHaveValue("some-["); + await user.type(input, "*"); + expect(input).toHaveValue("*"); expect(validator).toHaveBeenCalledWith(""); }); }); diff --git a/src/components/WelcomeModal/WelcomeModal.test.tsx b/src/components/WelcomeModal/WelcomeModal.test.tsx index fa69c8b88c..cc2e901215 100644 --- a/src/components/WelcomeModal/WelcomeModal.test.tsx +++ b/src/components/WelcomeModal/WelcomeModal.test.tsx @@ -1,5 +1,5 @@ import { MockedProvider } from "@apollo/client/testing"; -import { render, screen, waitFor } from "test_utils"; +import { render, screen, userEvent } from "test_utils"; import WelcomeModal from "./WelcomeModal"; describe("welcomeModal", () => { @@ -59,6 +59,7 @@ describe("welcomeModal", () => { }); it("clicking the pagination buttons change the slides", async () => { + const user = userEvent.setup(); render( { ); expect(screen.getByText("Slide 1")).toBeVisible(); expect(screen.queryByDataCy("carousel-dot-1")).toBeVisible(); - screen.queryByDataCy("carousel-dot-1").click(); - await waitFor(() => { - expect(screen.getByText("Slide 2")).toBeVisible(); - }); - screen.queryByDataCy("carousel-dot-0").click(); - await waitFor(() => { - expect(screen.getByText("Slide 1")).toBeVisible(); - }); + await user.click(screen.queryByDataCy("carousel-dot-1")); + expect(screen.getByText("Slide 2")).toBeVisible(); + await user.click(screen.queryByDataCy("carousel-dot-0")); + expect(screen.getByText("Slide 1")).toBeVisible(); }); }); diff --git a/src/constants/externalResources.ts b/src/constants/externalResources.ts index 412f8f91e5..52fa94100f 100644 --- a/src/constants/externalResources.ts +++ b/src/constants/externalResources.ts @@ -24,6 +24,8 @@ export const gitTagAliasesDocumentationUrl = `${projectDistroSettingsDocumentati export const githubChecksAliasesDocumentationUrl = `${projectDistroSettingsDocumentationUrl}#github-checks-aliases`; +export const githubMergeQueueDocumentationUrl = `${wikiBaseUrl}/Project-Configuration/Merge-Queue`; + export const cliDocumentationUrl = `${wikiBaseUrl}/CLI`; export const windowsPasswordRulesURL = diff --git a/src/context/toast/toast.test.tsx b/src/context/toast/toast.test.tsx index 0df3be7894..2826f18ae7 100644 --- a/src/context/toast/toast.test.tsx +++ b/src/context/toast/toast.test.tsx @@ -1,5 +1,11 @@ -import { renderHook } from "@testing-library/react-hooks"; -import { act, render, screen, userEvent, waitFor } from "test_utils"; +import { + renderHook, + act, + render, + screen, + userEvent, + waitFor, +} from "test_utils"; import { ToastProvider, useToastContext } from "."; import { RenderFakeToastContext } from "./__mocks__"; import { TOAST_TIMEOUT } from "./constants"; @@ -130,6 +136,7 @@ describe("toast", () => { describe("closing the toast", () => { it("should be able to close a toast by clicking the X button by default", async () => { + const user = userEvent.setup(); const { Component, hook } = renderComponentWithHook(); render(, { wrapper, @@ -138,7 +145,7 @@ describe("toast", () => { hook.current.info("test string"); }); expect(screen.getByDataCy("toast")).toBeInTheDocument(); - userEvent.click(screen.getByLabelText(closeIconLabel)); + await user.click(screen.getByLabelText(closeIconLabel)); await waitFor(() => { expect(screen.queryByDataCy("toast")).not.toBeInTheDocument(); }); @@ -157,6 +164,7 @@ describe("toast", () => { }); it("should trigger a callback function onClose", async () => { + const user = userEvent.setup(); const onClose = jest.fn(); const { Component, hook } = renderComponentWithHook(); render(, { @@ -167,7 +175,7 @@ describe("toast", () => { }); expect(screen.getByDataCy("toast")).toBeInTheDocument(); - userEvent.click(screen.getByLabelText(closeIconLabel)); + await user.click(screen.getByLabelText(closeIconLabel)); await waitFor(() => { expect(screen.queryByDataCy("toast")).not.toBeInTheDocument(); }); @@ -202,6 +210,7 @@ describe("toast", () => { describe("mocked toast", () => { it("should be able to mock the toast in a component test", async () => { + const user = userEvent.setup(); const ToastComponent: React.FC = () => { const dispatchToast = useToastContext(); return ( @@ -215,9 +224,8 @@ describe("mocked toast", () => { dispatchToast, useToastContext: useToastContextSpied, } = RenderFakeToastContext(); - render(); - userEvent.click(screen.getByText("Click Me")); + await user.click(screen.getByText("Click Me")); expect(useToastContextSpied).toHaveBeenCalledTimes(1); expect(dispatchToast.success).toHaveBeenCalledWith("test"); }); diff --git a/src/gql/GQLWrapper.tsx b/src/gql/GQLWrapper.tsx index b3d9ac7474..c89ee7d686 100644 --- a/src/gql/GQLWrapper.tsx +++ b/src/gql/GQLWrapper.tsx @@ -41,6 +41,9 @@ const cache = new InMemoryCache({ typePolicies: { Query: { fields: { + distroEvents: { + keyArgs: ["$distroId"], + }, projectEvents: { keyArgs: ["$identifier"], }, @@ -52,6 +55,20 @@ const cache = new InMemoryCache({ GeneralSubscription: { keyFields: false, }, + DistroEventsPayload: { + fields: { + count: { + merge(existing = 0, incoming = 0) { + return existing + incoming; + }, + }, + eventLogEntries: { + merge(existing = [], incoming = []) { + return [...existing, ...incoming]; + }, + }, + }, + }, ProjectEvents: { fields: { count: { diff --git a/src/gql/generated/types.ts b/src/gql/generated/types.ts index 61c1c68b5b..a070b1efa4 100644 --- a/src/gql/generated/types.ts +++ b/src/gql/generated/types.ts @@ -9,22 +9,31 @@ export type MakeOptional = Omit & { export type MakeMaybe = Omit & { [SubKey in K]: Maybe; }; +export type MakeEmpty< + T extends { [key: string]: unknown }, + K extends keyof T +> = { [_ in K]?: never }; +export type Incremental = + | T + | { + [P in keyof T]?: P extends " $fragmentName" | "__typename" ? T[P] : never; + }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { - ID: string; - String: string; - Boolean: boolean; - Int: number; - Float: number; - Duration: number; - Map: any; - StringMap: { [key: string]: any }; - Time: Date; + ID: { input: string; output: string }; + String: { input: string; output: string }; + Boolean: { input: boolean; output: boolean }; + Int: { input: number; output: number }; + Float: { input: number; output: number }; + Duration: { input: number; output: number }; + Map: { input: any; output: any }; + StringMap: { input: { [key: string]: any }; output: { [key: string]: any } }; + Time: { input: Date; output: Date }; }; export type AwsConfig = { __typename?: "AWSConfig"; - maxVolumeSizePerUser?: Maybe; + maxVolumeSizePerUser?: Maybe; pod?: Maybe; }; @@ -35,12 +44,12 @@ export type AwsPodConfig = { export type AbortInfo = { __typename?: "AbortInfo"; - buildVariantDisplayName: Scalars["String"]; - newVersion: Scalars["String"]; - prClosed: Scalars["Boolean"]; - taskDisplayName: Scalars["String"]; - taskID: Scalars["String"]; - user: Scalars["String"]; + buildVariantDisplayName: Scalars["String"]["output"]; + newVersion: Scalars["String"]["output"]; + prClosed: Scalars["Boolean"]["output"]; + taskDisplayName: Scalars["String"]["output"]; + taskID: Scalars["String"]["output"]; + user: Scalars["String"]["output"]; }; /** @@ -50,15 +59,25 @@ export type AbortInfo = { export type Annotation = { __typename?: "Annotation"; createdIssues?: Maybe>>; - id: Scalars["String"]; + id: Scalars["String"]["output"]; issues?: Maybe>>; metadataLinks?: Maybe>>; note?: Maybe; suspectedIssues?: Maybe>>; - taskExecution: Scalars["Int"]; - taskId: Scalars["String"]; - webhookConfigured: Scalars["Boolean"]; -}; + taskExecution: Scalars["Int"]["output"]; + taskId: Scalars["String"]["output"]; + webhookConfigured: Scalars["Boolean"]["output"]; +}; + +export enum Arch { + Linux_64Bit = "LINUX_64_BIT", + LinuxArm_64Bit = "LINUX_ARM_64_BIT", + LinuxPpc_64Bit = "LINUX_PPC_64_BIT", + LinuxZseries = "LINUX_ZSERIES", + Osx_64Bit = "OSX_64_BIT", + OsxArm_64Bit = "OSX_ARM_64_BIT", + Windows_64Bit = "WINDOWS_64_BIT", +} export enum BannerTheme { Announcement = "ANNOUNCEMENT", @@ -67,42 +86,48 @@ export enum BannerTheme { Warning = "WARNING", } +export enum BootstrapMethod { + LegacySsh = "LEGACY_SSH", + Ssh = "SSH", + UserData = "USER_DATA", +} + export type BootstrapSettings = { __typename?: "BootstrapSettings"; - clientDir: Scalars["String"]; - communication: Scalars["String"]; + clientDir: Scalars["String"]["output"]; + communication: CommunicationMethod; env: Array; - jasperBinaryDir: Scalars["String"]; - jasperCredentialsPath: Scalars["String"]; - method: Scalars["String"]; + jasperBinaryDir: Scalars["String"]["output"]; + jasperCredentialsPath: Scalars["String"]["output"]; + method: BootstrapMethod; preconditionScripts: Array; resourceLimits: ResourceLimits; - rootDir: Scalars["String"]; - serviceUser: Scalars["String"]; - shellPath: Scalars["String"]; + rootDir: Scalars["String"]["output"]; + serviceUser: Scalars["String"]["output"]; + shellPath: Scalars["String"]["output"]; }; export type BootstrapSettingsInput = { - clientDir: Scalars["String"]; - communication: Scalars["String"]; + clientDir: Scalars["String"]["input"]; + communication: CommunicationMethod; env: Array; - jasperBinaryDir: Scalars["String"]; - jasperCredentialsPath: Scalars["String"]; - method: Scalars["String"]; + jasperBinaryDir: Scalars["String"]["input"]; + jasperCredentialsPath: Scalars["String"]["input"]; + method: BootstrapMethod; preconditionScripts: Array; resourceLimits: ResourceLimitsInput; - rootDir: Scalars["String"]; - serviceUser: Scalars["String"]; - shellPath: Scalars["String"]; + rootDir: Scalars["String"]["input"]; + serviceUser: Scalars["String"]["input"]; + shellPath: Scalars["String"]["input"]; }; export type Build = { __typename?: "Build"; - actualMakespan: Scalars["Duration"]; - buildVariant: Scalars["String"]; - id: Scalars["String"]; - predictedMakespan: Scalars["Duration"]; - status: Scalars["String"]; + actualMakespan: Scalars["Duration"]["output"]; + buildVariant: Scalars["String"]["output"]; + id: Scalars["String"]["output"]; + predictedMakespan: Scalars["Duration"]["output"]; + status: Scalars["String"]["output"]; }; /** @@ -112,30 +137,30 @@ export type Build = { */ export type BuildBaron = { __typename?: "BuildBaron"; - bbTicketCreationDefined: Scalars["Boolean"]; - buildBaronConfigured: Scalars["Boolean"]; + bbTicketCreationDefined: Scalars["Boolean"]["output"]; + buildBaronConfigured: Scalars["Boolean"]["output"]; searchReturnInfo?: Maybe; }; export type BuildBaronSettings = { __typename?: "BuildBaronSettings"; - bfSuggestionFeaturesURL?: Maybe; - bfSuggestionPassword?: Maybe; - bfSuggestionServer?: Maybe; - bfSuggestionTimeoutSecs?: Maybe; - bfSuggestionUsername?: Maybe; - ticketCreateProject: Scalars["String"]; - ticketSearchProjects?: Maybe>; + bfSuggestionFeaturesURL?: Maybe; + bfSuggestionPassword?: Maybe; + bfSuggestionServer?: Maybe; + bfSuggestionTimeoutSecs?: Maybe; + bfSuggestionUsername?: Maybe; + ticketCreateProject: Scalars["String"]["output"]; + ticketSearchProjects?: Maybe>; }; export type BuildBaronSettingsInput = { - bfSuggestionFeaturesURL?: InputMaybe; - bfSuggestionPassword?: InputMaybe; - bfSuggestionServer?: InputMaybe; - bfSuggestionTimeoutSecs?: InputMaybe; - bfSuggestionUsername?: InputMaybe; - ticketCreateProject: Scalars["String"]; - ticketSearchProjects?: InputMaybe>; + bfSuggestionFeaturesURL?: InputMaybe; + bfSuggestionPassword?: InputMaybe; + bfSuggestionServer?: InputMaybe; + bfSuggestionTimeoutSecs?: InputMaybe; + bfSuggestionUsername?: InputMaybe; + ticketCreateProject: Scalars["String"]["input"]; + ticketSearchProjects?: InputMaybe>; }; /** @@ -143,30 +168,30 @@ export type BuildBaronSettingsInput = { * It stores values for statuses, tasks, and variants which are used to filter for matching versions. */ export type BuildVariantOptions = { - includeBaseTasks?: InputMaybe; - statuses?: InputMaybe>; - tasks?: InputMaybe>; - variants?: InputMaybe>; + includeBaseTasks?: InputMaybe; + statuses?: InputMaybe>; + tasks?: InputMaybe>; + variants?: InputMaybe>; }; export type BuildVariantTuple = { __typename?: "BuildVariantTuple"; - buildVariant: Scalars["String"]; - displayName: Scalars["String"]; + buildVariant: Scalars["String"]["output"]; + displayName: Scalars["String"]["output"]; }; export type ChildPatchAlias = { __typename?: "ChildPatchAlias"; - alias: Scalars["String"]; - patchId: Scalars["String"]; + alias: Scalars["String"]["output"]; + patchId: Scalars["String"]["output"]; }; export type ClientBinary = { __typename?: "ClientBinary"; - arch?: Maybe; - displayName?: Maybe; - os?: Maybe; - url?: Maybe; + arch?: Maybe; + displayName?: Maybe; + os?: Maybe; + url?: Maybe; }; /** @@ -176,7 +201,7 @@ export type ClientBinary = { export type ClientConfig = { __typename?: "ClientConfig"; clientBinaries?: Maybe>; - latestRevision?: Maybe; + latestRevision?: Maybe; }; export enum CloneMethod { @@ -195,49 +220,55 @@ export type CloudProviderConfig = { */ export type CommitQueue = { __typename?: "CommitQueue"; - message?: Maybe; - owner?: Maybe; - projectId?: Maybe; + message?: Maybe; + owner?: Maybe; + projectId?: Maybe; queue?: Maybe>; - repo?: Maybe; + repo?: Maybe; }; export type CommitQueueItem = { __typename?: "CommitQueueItem"; - enqueueTime?: Maybe; - issue?: Maybe; + enqueueTime?: Maybe; + issue?: Maybe; modules?: Maybe>; patch?: Maybe; - source?: Maybe; - version?: Maybe; + source?: Maybe; + version?: Maybe; }; export type CommitQueueParams = { __typename?: "CommitQueueParams"; - enabled?: Maybe; - mergeMethod: Scalars["String"]; + enabled?: Maybe; + mergeMethod: Scalars["String"]["output"]; mergeQueue: MergeQueue; - message: Scalars["String"]; + message: Scalars["String"]["output"]; }; export type CommitQueueParamsInput = { - enabled?: InputMaybe; - mergeMethod?: InputMaybe; + enabled?: InputMaybe; + mergeMethod?: InputMaybe; mergeQueue?: InputMaybe; - message?: InputMaybe; + message?: InputMaybe; }; +export enum CommunicationMethod { + LegacySsh = "LEGACY_SSH", + Rpc = "RPC", + Ssh = "SSH", +} + export type ContainerResources = { __typename?: "ContainerResources"; - cpu: Scalars["Int"]; - memoryMb: Scalars["Int"]; - name: Scalars["String"]; + cpu: Scalars["Int"]["output"]; + memoryMb: Scalars["Int"]["output"]; + name: Scalars["String"]["output"]; }; export type ContainerResourcesInput = { - cpu: Scalars["Int"]; - memoryMb: Scalars["Int"]; - name: Scalars["String"]; + cpu: Scalars["Int"]["input"]; + memoryMb: Scalars["Int"]["input"]; + name: Scalars["String"]["input"]; }; /** @@ -245,8 +276,8 @@ export type ContainerResourcesInput = { * It contains information about a distro to be duplicated. */ export type CopyDistroInput = { - distroIdToCopy: Scalars["String"]; - newDistroId: Scalars["String"]; + distroIdToCopy: Scalars["String"]["input"]; + newDistroId: Scalars["String"]["input"]; }; /** @@ -254,14 +285,14 @@ export type CopyDistroInput = { * It contains information about a project to be duplicated. */ export type CopyProjectInput = { - newProjectId?: InputMaybe; - newProjectIdentifier: Scalars["String"]; - projectIdToCopy: Scalars["String"]; + newProjectId?: InputMaybe; + newProjectIdentifier: Scalars["String"]["input"]; + projectIdToCopy: Scalars["String"]["input"]; }; /** CreateDistroInput is the input to the createDistro mutation. */ export type CreateDistroInput = { - newDistroId: Scalars["String"]; + newDistroId: Scalars["String"]["input"]; }; /** @@ -269,31 +300,31 @@ export type CreateDistroInput = { * It contains information about a new project to be created. */ export type CreateProjectInput = { - id?: InputMaybe; - identifier: Scalars["String"]; - owner: Scalars["String"]; - repo: Scalars["String"]; - repoRefId?: InputMaybe; + id?: InputMaybe; + identifier: Scalars["String"]["input"]; + owner: Scalars["String"]["input"]; + repo: Scalars["String"]["input"]; + repoRefId?: InputMaybe; }; /** DeleteDistroInput is the input to the deleteDistro mutation. */ export type DeleteDistroInput = { - distroId: Scalars["String"]; + distroId: Scalars["String"]["input"]; }; /** Return type representing whether a distro was deleted. */ export type DeleteDistroPayload = { __typename?: "DeleteDistroPayload"; - deletedDistroId: Scalars["String"]; + deletedDistroId: Scalars["String"]["output"]; }; export type Dependency = { __typename?: "Dependency"; - buildVariant: Scalars["String"]; + buildVariant: Scalars["String"]["output"]; metStatus: MetStatus; - name: Scalars["String"]; + name: Scalars["String"]["output"]; requiredStatus: RequiredStatus; - taskId: Scalars["String"]; + taskId: Scalars["String"]["output"]; }; export type DispatcherSettings = { @@ -311,106 +342,106 @@ export enum DispatcherVersion { } export type DisplayTask = { - ExecTasks: Array; - Name: Scalars["String"]; + ExecTasks: Array; + Name: Scalars["String"]["input"]; }; /** Distro models an environment configuration for a host. */ export type Distro = { __typename?: "Distro"; - aliases: Array; - arch: Scalars["String"]; - authorizedKeysFile: Scalars["String"]; + aliases: Array; + arch: Arch; + authorizedKeysFile: Scalars["String"]["output"]; bootstrapSettings: BootstrapSettings; cloneMethod: CloneMethod; - containerPool: Scalars["String"]; - disableShallowClone: Scalars["Boolean"]; - disabled: Scalars["Boolean"]; + containerPool: Scalars["String"]["output"]; + disableShallowClone: Scalars["Boolean"]["output"]; + disabled: Scalars["Boolean"]["output"]; dispatcherSettings: DispatcherSettings; expansions: Array; finderSettings: FinderSettings; homeVolumeSettings: HomeVolumeSettings; hostAllocatorSettings: HostAllocatorSettings; iceCreamSettings: IceCreamSettings; - isCluster: Scalars["Boolean"]; - isVirtualWorkStation: Scalars["Boolean"]; - name: Scalars["String"]; - note: Scalars["String"]; + isCluster: Scalars["Boolean"]["output"]; + isVirtualWorkStation: Scalars["Boolean"]["output"]; + name: Scalars["String"]["output"]; + note: Scalars["String"]["output"]; plannerSettings: PlannerSettings; - provider: Scalars["String"]; - providerSettingsList: Array; - setup: Scalars["String"]; - setupAsSudo: Scalars["Boolean"]; - sshKey: Scalars["String"]; - sshOptions: Array; - user: Scalars["String"]; - userSpawnAllowed: Scalars["Boolean"]; - validProjects: Array>; - workDir: Scalars["String"]; + provider: Provider; + providerSettingsList: Array; + setup: Scalars["String"]["output"]; + setupAsSudo: Scalars["Boolean"]["output"]; + sshKey: Scalars["String"]["output"]; + sshOptions: Array; + user: Scalars["String"]["output"]; + userSpawnAllowed: Scalars["Boolean"]["output"]; + validProjects: Array>; + workDir: Scalars["String"]["output"]; }; export type DistroEvent = { __typename?: "DistroEvent"; - after?: Maybe; - before?: Maybe; - data?: Maybe; - timestamp: Scalars["Time"]; - user: Scalars["String"]; + after?: Maybe; + before?: Maybe; + data?: Maybe; + timestamp: Scalars["Time"]["output"]; + user: Scalars["String"]["output"]; }; /** DistroEventsInput is the input to the distroEvents query. */ export type DistroEventsInput = { - before?: InputMaybe; - distroId: Scalars["String"]; - limit?: InputMaybe; + before?: InputMaybe; + distroId: Scalars["String"]["input"]; + limit?: InputMaybe; }; export type DistroEventsPayload = { __typename?: "DistroEventsPayload"; - count: Scalars["Int"]; + count: Scalars["Int"]["output"]; eventLogEntries: Array; }; export type DistroInfo = { __typename?: "DistroInfo"; - bootstrapMethod?: Maybe; - id?: Maybe; - isVirtualWorkStation?: Maybe; - isWindows?: Maybe; - user?: Maybe; - workDir?: Maybe; + bootstrapMethod?: Maybe; + id?: Maybe; + isVirtualWorkStation?: Maybe; + isWindows?: Maybe; + user?: Maybe; + workDir?: Maybe; }; export type DistroInput = { - aliases: Array; - arch: Scalars["String"]; - authorizedKeysFile: Scalars["String"]; + aliases: Array; + arch: Arch; + authorizedKeysFile: Scalars["String"]["input"]; bootstrapSettings: BootstrapSettingsInput; cloneMethod: CloneMethod; - containerPool: Scalars["String"]; - disableShallowClone: Scalars["Boolean"]; - disabled: Scalars["Boolean"]; + containerPool: Scalars["String"]["input"]; + disableShallowClone: Scalars["Boolean"]["input"]; + disabled: Scalars["Boolean"]["input"]; dispatcherSettings: DispatcherSettingsInput; expansions: Array; finderSettings: FinderSettingsInput; homeVolumeSettings: HomeVolumeSettingsInput; hostAllocatorSettings: HostAllocatorSettingsInput; iceCreamSettings: IceCreamSettingsInput; - isCluster: Scalars["Boolean"]; - isVirtualWorkStation: Scalars["Boolean"]; - name: Scalars["String"]; - note: Scalars["String"]; + isCluster: Scalars["Boolean"]["input"]; + isVirtualWorkStation: Scalars["Boolean"]["input"]; + name: Scalars["String"]["input"]; + note: Scalars["String"]["input"]; plannerSettings: PlannerSettingsInput; - provider: Scalars["String"]; - providerSettingsList: Array; - setup: Scalars["String"]; - setupAsSudo: Scalars["Boolean"]; - sshKey: Scalars["String"]; - sshOptions: Array; - user: Scalars["String"]; - userSpawnAllowed: Scalars["Boolean"]; - validProjects: Array; - workDir: Scalars["String"]; + provider: Provider; + providerSettingsList: Array; + setup: Scalars["String"]["input"]; + setupAsSudo: Scalars["Boolean"]["input"]; + sshKey: Scalars["String"]["input"]; + sshOptions: Array; + user: Scalars["String"]["input"]; + userSpawnAllowed: Scalars["Boolean"]["input"]; + validProjects: Array; + workDir: Scalars["String"]["input"]; }; export enum DistroOnSaveOperation { @@ -422,13 +453,13 @@ export enum DistroOnSaveOperation { export type DistroPermissions = { __typename?: "DistroPermissions"; - admin: Scalars["Boolean"]; - edit: Scalars["Boolean"]; - view: Scalars["Boolean"]; + admin: Scalars["Boolean"]["output"]; + edit: Scalars["Boolean"]["output"]; + view: Scalars["Boolean"]["output"]; }; export type DistroPermissionsOptions = { - distroId: Scalars["String"]; + distroId: Scalars["String"]["input"]; }; export enum DistroSettingsAccess { @@ -440,8 +471,8 @@ export enum DistroSettingsAccess { export type EcsConfig = { __typename?: "ECSConfig"; - maxCPU: Scalars["Int"]; - maxMemoryMb: Scalars["Int"]; + maxCPU: Scalars["Int"]["output"]; + maxMemoryMb: Scalars["Int"]["output"]; }; /** @@ -451,72 +482,78 @@ export type EcsConfig = { export type EditSpawnHostInput = { addedInstanceTags?: InputMaybe>; deletedInstanceTags?: InputMaybe>; - displayName?: InputMaybe; - expiration?: InputMaybe; - hostId: Scalars["String"]; - instanceType?: InputMaybe; - noExpiration?: InputMaybe; + displayName?: InputMaybe; + expiration?: InputMaybe; + hostId: Scalars["String"]["input"]; + instanceType?: InputMaybe; + noExpiration?: InputMaybe; publicKey?: InputMaybe; - savePublicKey?: InputMaybe; - servicePassword?: InputMaybe; - volume?: InputMaybe; + savePublicKey?: InputMaybe; + servicePassword?: InputMaybe; + volume?: InputMaybe; }; export type EnvVar = { __typename?: "EnvVar"; - key: Scalars["String"]; - value: Scalars["String"]; + key: Scalars["String"]["output"]; + value: Scalars["String"]["output"]; }; export type EnvVarInput = { - key: Scalars["String"]; - value: Scalars["String"]; + key: Scalars["String"]["input"]; + value: Scalars["String"]["input"]; }; export type Expansion = { __typename?: "Expansion"; - key: Scalars["String"]; - value: Scalars["String"]; + key: Scalars["String"]["output"]; + value: Scalars["String"]["output"]; }; export type ExpansionInput = { - key: Scalars["String"]; - value: Scalars["String"]; + key: Scalars["String"]["input"]; + value: Scalars["String"]["input"]; }; export type ExternalLink = { __typename?: "ExternalLink"; - displayName: Scalars["String"]; - requesters: Array; - urlTemplate: Scalars["String"]; + displayName: Scalars["String"]["output"]; + requesters: Array; + urlTemplate: Scalars["String"]["output"]; }; export type ExternalLinkForMetadata = { __typename?: "ExternalLinkForMetadata"; - displayName: Scalars["String"]; - url: Scalars["String"]; + displayName: Scalars["String"]["output"]; + url: Scalars["String"]["output"]; }; export type ExternalLinkInput = { - displayName: Scalars["String"]; - requesters: Array; - urlTemplate: Scalars["String"]; + displayName: Scalars["String"]["input"]; + requesters: Array; + urlTemplate: Scalars["String"]["input"]; }; +export enum FeedbackRule { + Default = "DEFAULT", + NoFeedback = "NO_FEEDBACK", + WaitsOverThresh = "WAITS_OVER_THRESH", +} + export type File = { __typename?: "File"; - link: Scalars["String"]; - name: Scalars["String"]; - visibility: Scalars["String"]; + link: Scalars["String"]["output"]; + name: Scalars["String"]["output"]; + visibility: Scalars["String"]["output"]; }; export type FileDiff = { __typename?: "FileDiff"; - additions: Scalars["Int"]; - deletions: Scalars["Int"]; - description: Scalars["String"]; - diffLink: Scalars["String"]; - fileName: Scalars["String"]; + additions: Scalars["Int"]["output"]; + deletions: Scalars["Int"]["output"]; + description: Scalars["String"]["output"]; + diffLink: Scalars["String"]["output"]; + fileName: Scalars["String"]["output"]; }; export type FinderSettings = { @@ -537,35 +574,35 @@ export enum FinderVersion { export type GeneralSubscription = { __typename?: "GeneralSubscription"; - id: Scalars["String"]; - ownerType: Scalars["String"]; + id: Scalars["String"]["output"]; + ownerType: Scalars["String"]["output"]; regexSelectors: Array; - resourceType: Scalars["String"]; + resourceType: Scalars["String"]["output"]; selectors: Array; subscriber?: Maybe; - trigger: Scalars["String"]; - triggerData?: Maybe; + trigger: Scalars["String"]["output"]; + triggerData?: Maybe; }; export type GitTag = { __typename?: "GitTag"; - pusher: Scalars["String"]; - tag: Scalars["String"]; + pusher: Scalars["String"]["output"]; + tag: Scalars["String"]["output"]; }; export type GithubCheckSubscriber = { __typename?: "GithubCheckSubscriber"; - owner: Scalars["String"]; - ref: Scalars["String"]; - repo: Scalars["String"]; + owner: Scalars["String"]["output"]; + ref: Scalars["String"]["output"]; + repo: Scalars["String"]["output"]; }; export type GithubPrSubscriber = { __typename?: "GithubPRSubscriber"; - owner: Scalars["String"]; - prNumber?: Maybe; - ref: Scalars["String"]; - repo: Scalars["String"]; + owner: Scalars["String"]["output"]; + prNumber?: Maybe; + ref: Scalars["String"]["output"]; + repo: Scalars["String"]["output"]; }; /** @@ -574,32 +611,32 @@ export type GithubPrSubscriber = { */ export type GithubProjectConflicts = { __typename?: "GithubProjectConflicts"; - commitCheckIdentifiers?: Maybe>; - commitQueueIdentifiers?: Maybe>; - prTestingIdentifiers?: Maybe>; + commitCheckIdentifiers?: Maybe>; + commitQueueIdentifiers?: Maybe>; + prTestingIdentifiers?: Maybe>; }; export type GithubUser = { __typename?: "GithubUser"; - lastKnownAs?: Maybe; - uid?: Maybe; + lastKnownAs?: Maybe; + uid?: Maybe; }; export type GithubUserInput = { - lastKnownAs?: InputMaybe; + lastKnownAs?: InputMaybe; }; export type GroupedBuildVariant = { __typename?: "GroupedBuildVariant"; - displayName: Scalars["String"]; + displayName: Scalars["String"]["output"]; tasks?: Maybe>>; - variant: Scalars["String"]; + variant: Scalars["String"]["output"]; }; export type GroupedFiles = { __typename?: "GroupedFiles"; files?: Maybe>; - taskName?: Maybe; + taskName?: Maybe; }; /** @@ -608,108 +645,112 @@ export type GroupedFiles = { */ export type GroupedProjects = { __typename?: "GroupedProjects"; - groupDisplayName: Scalars["String"]; + groupDisplayName: Scalars["String"]["output"]; projects: Array; repo?: Maybe; }; export type GroupedTaskStatusCount = { __typename?: "GroupedTaskStatusCount"; - displayName: Scalars["String"]; + displayName: Scalars["String"]["output"]; statusCounts: Array; - variant: Scalars["String"]; + variant: Scalars["String"]["output"]; }; export type HomeVolumeSettings = { __typename?: "HomeVolumeSettings"; - formatCommand: Scalars["String"]; + formatCommand: Scalars["String"]["output"]; }; export type HomeVolumeSettingsInput = { - formatCommand: Scalars["String"]; + formatCommand: Scalars["String"]["input"]; }; /** Host models a host, which are used for things like running tasks or as virtual workstations. */ export type Host = { __typename?: "Host"; - ami?: Maybe; - availabilityZone?: Maybe; - displayName?: Maybe; + ami?: Maybe; + availabilityZone?: Maybe; + displayName?: Maybe; distro?: Maybe; - distroId?: Maybe; - elapsed?: Maybe; - expiration?: Maybe; + distroId?: Maybe; + elapsed?: Maybe; + expiration?: Maybe; homeVolume?: Maybe; - homeVolumeID?: Maybe; - hostUrl: Scalars["String"]; - id: Scalars["ID"]; + homeVolumeID?: Maybe; + hostUrl: Scalars["String"]["output"]; + id: Scalars["ID"]["output"]; instanceTags: Array; - instanceType?: Maybe; - lastCommunicationTime?: Maybe; - noExpiration: Scalars["Boolean"]; - provider: Scalars["String"]; + instanceType?: Maybe; + lastCommunicationTime?: Maybe; + noExpiration: Scalars["Boolean"]["output"]; + provider: Scalars["String"]["output"]; runningTask?: Maybe; - startedBy: Scalars["String"]; - status: Scalars["String"]; - tag: Scalars["String"]; - totalIdleTime?: Maybe; - uptime?: Maybe; - user?: Maybe; + startedBy: Scalars["String"]["output"]; + status: Scalars["String"]["output"]; + tag: Scalars["String"]["output"]; + totalIdleTime?: Maybe; + uptime?: Maybe; + user?: Maybe; volumes: Array; }; export type HostAllocatorSettings = { __typename?: "HostAllocatorSettings"; - acceptableHostIdleTime: Scalars["Duration"]; - feedbackRule: Scalars["String"]; - futureHostFraction: Scalars["Float"]; - hostsOverallocatedRule: Scalars["String"]; - maximumHosts: Scalars["Int"]; - minimumHosts: Scalars["Int"]; - roundingRule: Scalars["String"]; - version: Scalars["String"]; + acceptableHostIdleTime: Scalars["Duration"]["output"]; + feedbackRule: FeedbackRule; + futureHostFraction: Scalars["Float"]["output"]; + hostsOverallocatedRule: OverallocatedRule; + maximumHosts: Scalars["Int"]["output"]; + minimumHosts: Scalars["Int"]["output"]; + roundingRule: RoundingRule; + version: HostAllocatorVersion; }; export type HostAllocatorSettingsInput = { - acceptableHostIdleTime: Scalars["Int"]; - feedbackRule: Scalars["String"]; - futureHostFraction: Scalars["Float"]; - hostsOverallocatedRule: Scalars["String"]; - maximumHosts: Scalars["Int"]; - minimumHosts: Scalars["Int"]; - roundingRule: Scalars["String"]; - version: Scalars["String"]; -}; + acceptableHostIdleTime: Scalars["Int"]["input"]; + feedbackRule: FeedbackRule; + futureHostFraction: Scalars["Float"]["input"]; + hostsOverallocatedRule: OverallocatedRule; + maximumHosts: Scalars["Int"]["input"]; + minimumHosts: Scalars["Int"]["input"]; + roundingRule: RoundingRule; + version: HostAllocatorVersion; +}; + +export enum HostAllocatorVersion { + Utilization = "UTILIZATION", +} export type HostEventLogData = { __typename?: "HostEventLogData"; - agentBuild: Scalars["String"]; - agentRevision: Scalars["String"]; - duration: Scalars["Duration"]; - execution: Scalars["String"]; - hostname: Scalars["String"]; - jasperRevision: Scalars["String"]; - logs: Scalars["String"]; - monitorOp: Scalars["String"]; - newStatus: Scalars["String"]; - oldStatus: Scalars["String"]; - provisioningMethod: Scalars["String"]; - successful: Scalars["Boolean"]; - taskId: Scalars["String"]; - taskPid: Scalars["String"]; - taskStatus: Scalars["String"]; - user: Scalars["String"]; + agentBuild: Scalars["String"]["output"]; + agentRevision: Scalars["String"]["output"]; + duration: Scalars["Duration"]["output"]; + execution: Scalars["String"]["output"]; + hostname: Scalars["String"]["output"]; + jasperRevision: Scalars["String"]["output"]; + logs: Scalars["String"]["output"]; + monitorOp: Scalars["String"]["output"]; + newStatus: Scalars["String"]["output"]; + oldStatus: Scalars["String"]["output"]; + provisioningMethod: Scalars["String"]["output"]; + successful: Scalars["Boolean"]["output"]; + taskId: Scalars["String"]["output"]; + taskPid: Scalars["String"]["output"]; + taskStatus: Scalars["String"]["output"]; + user: Scalars["String"]["output"]; }; export type HostEventLogEntry = { __typename?: "HostEventLogEntry"; data: HostEventLogData; - eventType?: Maybe; - id: Scalars["String"]; - processedAt: Scalars["Time"]; - resourceId: Scalars["String"]; - resourceType: Scalars["String"]; - timestamp?: Maybe; + eventType?: Maybe; + id: Scalars["String"]["output"]; + processedAt: Scalars["Time"]["output"]; + resourceId: Scalars["String"]["output"]; + resourceType: Scalars["String"]["output"]; + timestamp?: Maybe; }; /** @@ -718,7 +759,7 @@ export type HostEventLogEntry = { */ export type HostEvents = { __typename?: "HostEvents"; - count: Scalars["Int"]; + count: Scalars["Int"]["output"]; eventLogEntries: Array; }; @@ -739,118 +780,118 @@ export enum HostSortBy { */ export type HostsResponse = { __typename?: "HostsResponse"; - filteredHostsCount?: Maybe; + filteredHostsCount?: Maybe; hosts: Array; - totalHostsCount: Scalars["Int"]; + totalHostsCount: Scalars["Int"]["output"]; }; export type IceCreamSettings = { __typename?: "IceCreamSettings"; - configPath: Scalars["String"]; - schedulerHost: Scalars["String"]; + configPath: Scalars["String"]["output"]; + schedulerHost: Scalars["String"]["output"]; }; export type IceCreamSettingsInput = { - configPath: Scalars["String"]; - schedulerHost: Scalars["String"]; + configPath: Scalars["String"]["input"]; + schedulerHost: Scalars["String"]["input"]; }; export type InstanceTag = { __typename?: "InstanceTag"; - canBeModified: Scalars["Boolean"]; - key: Scalars["String"]; - value: Scalars["String"]; + canBeModified: Scalars["Boolean"]["output"]; + key: Scalars["String"]["output"]; + value: Scalars["String"]["output"]; }; export type InstanceTagInput = { - key: Scalars["String"]; - value: Scalars["String"]; + key: Scalars["String"]["input"]; + value: Scalars["String"]["input"]; }; export type IssueLink = { __typename?: "IssueLink"; - confidenceScore?: Maybe; - issueKey?: Maybe; + confidenceScore?: Maybe; + issueKey?: Maybe; jiraTicket?: Maybe; source?: Maybe; - url?: Maybe; + url?: Maybe; }; /** IssueLinkInput is an input parameter to the annotation mutations. */ export type IssueLinkInput = { - confidenceScore?: InputMaybe; - issueKey: Scalars["String"]; - url: Scalars["String"]; + confidenceScore?: InputMaybe; + issueKey: Scalars["String"]["input"]; + url: Scalars["String"]["input"]; }; export type JiraConfig = { __typename?: "JiraConfig"; - host?: Maybe; + host?: Maybe; }; export type JiraField = { __typename?: "JiraField"; - displayText: Scalars["String"]; - field: Scalars["String"]; + displayText: Scalars["String"]["output"]; + field: Scalars["String"]["output"]; }; export type JiraFieldInput = { - displayText: Scalars["String"]; - field: Scalars["String"]; + displayText: Scalars["String"]["input"]; + field: Scalars["String"]["input"]; }; export type JiraIssueSubscriber = { __typename?: "JiraIssueSubscriber"; - issueType: Scalars["String"]; - project: Scalars["String"]; + issueType: Scalars["String"]["output"]; + project: Scalars["String"]["output"]; }; export type JiraIssueSubscriberInput = { - issueType: Scalars["String"]; - project: Scalars["String"]; + issueType: Scalars["String"]["input"]; + project: Scalars["String"]["input"]; }; export type JiraStatus = { __typename?: "JiraStatus"; - id: Scalars["String"]; - name: Scalars["String"]; + id: Scalars["String"]["output"]; + name: Scalars["String"]["output"]; }; export type JiraTicket = { __typename?: "JiraTicket"; fields: TicketFields; - key: Scalars["String"]; + key: Scalars["String"]["output"]; }; export type LogMessage = { __typename?: "LogMessage"; - message?: Maybe; - severity?: Maybe; - timestamp?: Maybe; - type?: Maybe; - version?: Maybe; + message?: Maybe; + severity?: Maybe; + timestamp?: Maybe; + type?: Maybe; + version?: Maybe; }; export type LogkeeperBuild = { __typename?: "LogkeeperBuild"; - buildNum: Scalars["Int"]; - builder: Scalars["String"]; - id: Scalars["String"]; + buildNum: Scalars["Int"]["output"]; + builder: Scalars["String"]["output"]; + id: Scalars["String"]["output"]; task: Task; - taskExecution: Scalars["Int"]; - taskId: Scalars["String"]; + taskExecution: Scalars["Int"]["output"]; + taskId: Scalars["String"]["output"]; tests: Array; }; export type LogkeeperTest = { __typename?: "LogkeeperTest"; - buildId: Scalars["String"]; - command: Scalars["String"]; - id: Scalars["String"]; - name: Scalars["String"]; - phase: Scalars["String"]; - taskExecution: Scalars["Int"]; - taskId: Scalars["String"]; + buildId: Scalars["String"]["output"]; + command: Scalars["String"]["output"]; + id: Scalars["String"]["output"]; + name: Scalars["String"]["output"]; + phase: Scalars["String"]["output"]; + taskExecution: Scalars["Int"]["output"]; + taskId: Scalars["String"]["output"]; }; export type MainlineCommitVersion = { @@ -865,8 +906,8 @@ export type MainlineCommitVersion = { */ export type MainlineCommits = { __typename?: "MainlineCommits"; - nextPageOrderNumber?: Maybe; - prevPageOrderNumber?: Maybe; + nextPageOrderNumber?: Maybe; + prevPageOrderNumber?: Maybe; versions: Array; }; @@ -875,22 +916,22 @@ export type MainlineCommits = { * Its fields determine what mainline commits we fetch for a given projectID. */ export type MainlineCommitsOptions = { - limit?: InputMaybe; - projectIdentifier: Scalars["String"]; - requesters?: InputMaybe>; - shouldCollapse?: InputMaybe; - skipOrderNumber?: InputMaybe; + limit?: InputMaybe; + projectIdentifier: Scalars["String"]["input"]; + requesters?: InputMaybe>; + shouldCollapse?: InputMaybe; + skipOrderNumber?: InputMaybe; }; export type Manifest = { __typename?: "Manifest"; - branch: Scalars["String"]; - id: Scalars["String"]; - isBase: Scalars["Boolean"]; - moduleOverrides?: Maybe; - modules?: Maybe; - project: Scalars["String"]; - revision: Scalars["String"]; + branch: Scalars["String"]["output"]; + id: Scalars["String"]["output"]; + isBase: Scalars["Boolean"]["output"]; + moduleOverrides?: Maybe; + modules?: Maybe; + project: Scalars["String"]["output"]; + revision: Scalars["String"]["output"]; }; export enum MergeQueue { @@ -908,27 +949,27 @@ export enum MetStatus { export type MetadataLink = { __typename?: "MetadataLink"; source?: Maybe; - text: Scalars["String"]; - url: Scalars["String"]; + text: Scalars["String"]["output"]; + url: Scalars["String"]["output"]; }; export type MetadataLinkInput = { - text: Scalars["String"]; - url: Scalars["String"]; + text: Scalars["String"]["input"]; + url: Scalars["String"]["input"]; }; export type Module = { __typename?: "Module"; - issue?: Maybe; - module?: Maybe; + issue?: Maybe; + module?: Maybe; }; export type ModuleCodeChange = { __typename?: "ModuleCodeChange"; - branchName: Scalars["String"]; + branchName: Scalars["String"]["output"]; fileDiffs: Array; - htmlLink: Scalars["String"]; - rawLink: Scalars["String"]; + htmlLink: Scalars["String"]["output"]; + rawLink: Scalars["String"]["output"]; }; /** @@ -936,87 +977,87 @@ export type ModuleCodeChange = { * It contains information used to move a project to a a new owner and repo. */ export type MoveProjectInput = { - newOwner: Scalars["String"]; - newRepo: Scalars["String"]; - projectId: Scalars["String"]; + newOwner: Scalars["String"]["input"]; + newRepo: Scalars["String"]["input"]; + projectId: Scalars["String"]["input"]; }; export type Mutation = { __typename?: "Mutation"; abortTask: Task; - addAnnotationIssue: Scalars["Boolean"]; + addAnnotationIssue: Scalars["Boolean"]["output"]; addFavoriteProject: Project; attachProjectToNewRepo: Project; attachProjectToRepo: Project; - attachVolumeToHost: Scalars["Boolean"]; - bbCreateTicket: Scalars["Boolean"]; - clearMySubscriptions: Scalars["Int"]; + attachVolumeToHost: Scalars["Boolean"]["output"]; + bbCreateTicket: Scalars["Boolean"]["output"]; + clearMySubscriptions: Scalars["Int"]["output"]; copyDistro: NewDistroPayload; copyProject: Project; createDistro: NewDistroPayload; createProject: Project; createPublicKey: Array; - deactivateStepbackTask: Scalars["Boolean"]; - defaultSectionToRepo?: Maybe; + deactivateStepbackTask: Scalars["Boolean"]["output"]; + defaultSectionToRepo?: Maybe; deleteDistro: DeleteDistroPayload; - deleteProject: Scalars["Boolean"]; - deleteSubscriptions: Scalars["Int"]; + deleteProject: Scalars["Boolean"]["output"]; + deleteSubscriptions: Scalars["Int"]["output"]; detachProjectFromRepo: Project; - detachVolumeFromHost: Scalars["Boolean"]; - editAnnotationNote: Scalars["Boolean"]; + detachVolumeFromHost: Scalars["Boolean"]["output"]; + editAnnotationNote: Scalars["Boolean"]["output"]; editSpawnHost: Host; enqueuePatch: Patch; - forceRepotrackerRun: Scalars["Boolean"]; - migrateVolume: Scalars["Boolean"]; - moveAnnotationIssue: Scalars["Boolean"]; + forceRepotrackerRun: Scalars["Boolean"]["output"]; + migrateVolume: Scalars["Boolean"]["output"]; + moveAnnotationIssue: Scalars["Boolean"]["output"]; overrideTaskDependencies: Task; - promoteVarsToRepo: Scalars["Boolean"]; - removeAnnotationIssue: Scalars["Boolean"]; + promoteVarsToRepo: Scalars["Boolean"]["output"]; + removeAnnotationIssue: Scalars["Boolean"]["output"]; removeFavoriteProject: Project; - removeItemFromCommitQueue?: Maybe; + removeItemFromCommitQueue?: Maybe; removePublicKey: Array; - removeVolume: Scalars["Boolean"]; - reprovisionToNew: Scalars["Int"]; - restartJasper: Scalars["Int"]; + removeVolume: Scalars["Boolean"]["output"]; + reprovisionToNew: Scalars["Int"]["output"]; + restartJasper: Scalars["Int"]["output"]; restartTask: Task; restartVersions?: Maybe>; saveDistro: SaveDistroPayload; saveProjectSettingsForSection: ProjectSettings; saveRepoSettingsForSection: RepoSettings; - saveSubscription: Scalars["Boolean"]; + saveSubscription: Scalars["Boolean"]["output"]; schedulePatch: Patch; - schedulePatchTasks?: Maybe; + schedulePatchTasks?: Maybe; scheduleTasks: Array; scheduleUndispatchedBaseTasks?: Maybe>; - setAnnotationMetadataLinks: Scalars["Boolean"]; - setPatchPriority?: Maybe; + setAnnotationMetadataLinks: Scalars["Boolean"]["output"]; + setPatchPriority?: Maybe; /** setPatchVisibility takes a list of patch ids and a boolean to set the visibility on the my patches queries */ setPatchVisibility: Array; setTaskPriority: Task; spawnHost: Host; - spawnVolume: Scalars["Boolean"]; - unschedulePatchTasks?: Maybe; + spawnVolume: Scalars["Boolean"]["output"]; + unschedulePatchTasks?: Maybe; unscheduleTask: Task; - updateHostStatus: Scalars["Int"]; + updateHostStatus: Scalars["Int"]["output"]; updatePublicKey: Array; updateSpawnHostStatus: Host; - updateUserSettings: Scalars["Boolean"]; - updateVolume: Scalars["Boolean"]; + updateUserSettings: Scalars["Boolean"]["output"]; + updateVolume: Scalars["Boolean"]["output"]; }; export type MutationAbortTaskArgs = { - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }; export type MutationAddAnnotationIssueArgs = { apiIssue: IssueLinkInput; - execution: Scalars["Int"]; - isIssue: Scalars["Boolean"]; - taskId: Scalars["String"]; + execution: Scalars["Int"]["input"]; + isIssue: Scalars["Boolean"]["input"]; + taskId: Scalars["String"]["input"]; }; export type MutationAddFavoriteProjectArgs = { - identifier: Scalars["String"]; + identifier: Scalars["String"]["input"]; }; export type MutationAttachProjectToNewRepoArgs = { @@ -1024,7 +1065,7 @@ export type MutationAttachProjectToNewRepoArgs = { }; export type MutationAttachProjectToRepoArgs = { - projectId: Scalars["String"]; + projectId: Scalars["String"]["input"]; }; export type MutationAttachVolumeToHostArgs = { @@ -1032,8 +1073,8 @@ export type MutationAttachVolumeToHostArgs = { }; export type MutationBbCreateTicketArgs = { - execution?: InputMaybe; - taskId: Scalars["String"]; + execution?: InputMaybe; + taskId: Scalars["String"]["input"]; }; export type MutationCopyDistroArgs = { @@ -1042,7 +1083,7 @@ export type MutationCopyDistroArgs = { export type MutationCopyProjectArgs = { project: CopyProjectInput; - requestS3Creds?: InputMaybe; + requestS3Creds?: InputMaybe; }; export type MutationCreateDistroArgs = { @@ -1051,7 +1092,7 @@ export type MutationCreateDistroArgs = { export type MutationCreateProjectArgs = { project: CreateProjectInput; - requestS3Creds?: InputMaybe; + requestS3Creds?: InputMaybe; }; export type MutationCreatePublicKeyArgs = { @@ -1059,13 +1100,13 @@ export type MutationCreatePublicKeyArgs = { }; export type MutationDeactivateStepbackTaskArgs = { - buildVariantName: Scalars["String"]; - projectId: Scalars["String"]; - taskName: Scalars["String"]; + buildVariantName: Scalars["String"]["input"]; + projectId: Scalars["String"]["input"]; + taskName: Scalars["String"]["input"]; }; export type MutationDefaultSectionToRepoArgs = { - projectId: Scalars["String"]; + projectId: Scalars["String"]["input"]; section: ProjectSettingsSection; }; @@ -1074,26 +1115,26 @@ export type MutationDeleteDistroArgs = { }; export type MutationDeleteProjectArgs = { - projectId: Scalars["String"]; + projectId: Scalars["String"]["input"]; }; export type MutationDeleteSubscriptionsArgs = { - subscriptionIds: Array; + subscriptionIds: Array; }; export type MutationDetachProjectFromRepoArgs = { - projectId: Scalars["String"]; + projectId: Scalars["String"]["input"]; }; export type MutationDetachVolumeFromHostArgs = { - volumeId: Scalars["String"]; + volumeId: Scalars["String"]["input"]; }; export type MutationEditAnnotationNoteArgs = { - execution: Scalars["Int"]; - newMessage: Scalars["String"]; - originalMessage: Scalars["String"]; - taskId: Scalars["String"]; + execution: Scalars["Int"]["input"]; + newMessage: Scalars["String"]["input"]; + originalMessage: Scalars["String"]["input"]; + taskId: Scalars["String"]["input"]; }; export type MutationEditSpawnHostArgs = { @@ -1101,75 +1142,75 @@ export type MutationEditSpawnHostArgs = { }; export type MutationEnqueuePatchArgs = { - commitMessage?: InputMaybe; - patchId: Scalars["String"]; + commitMessage?: InputMaybe; + patchId: Scalars["String"]["input"]; }; export type MutationForceRepotrackerRunArgs = { - projectId: Scalars["String"]; + projectId: Scalars["String"]["input"]; }; export type MutationMigrateVolumeArgs = { spawnHostInput?: InputMaybe; - volumeId: Scalars["String"]; + volumeId: Scalars["String"]["input"]; }; export type MutationMoveAnnotationIssueArgs = { apiIssue: IssueLinkInput; - execution: Scalars["Int"]; - isIssue: Scalars["Boolean"]; - taskId: Scalars["String"]; + execution: Scalars["Int"]["input"]; + isIssue: Scalars["Boolean"]["input"]; + taskId: Scalars["String"]["input"]; }; export type MutationOverrideTaskDependenciesArgs = { - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }; export type MutationPromoteVarsToRepoArgs = { - projectId: Scalars["String"]; - varNames: Array; + projectId: Scalars["String"]["input"]; + varNames: Array; }; export type MutationRemoveAnnotationIssueArgs = { apiIssue: IssueLinkInput; - execution: Scalars["Int"]; - isIssue: Scalars["Boolean"]; - taskId: Scalars["String"]; + execution: Scalars["Int"]["input"]; + isIssue: Scalars["Boolean"]["input"]; + taskId: Scalars["String"]["input"]; }; export type MutationRemoveFavoriteProjectArgs = { - identifier: Scalars["String"]; + identifier: Scalars["String"]["input"]; }; export type MutationRemoveItemFromCommitQueueArgs = { - commitQueueId: Scalars["String"]; - issue: Scalars["String"]; + commitQueueId: Scalars["String"]["input"]; + issue: Scalars["String"]["input"]; }; export type MutationRemovePublicKeyArgs = { - keyName: Scalars["String"]; + keyName: Scalars["String"]["input"]; }; export type MutationRemoveVolumeArgs = { - volumeId: Scalars["String"]; + volumeId: Scalars["String"]["input"]; }; export type MutationReprovisionToNewArgs = { - hostIds: Array; + hostIds: Array; }; export type MutationRestartJasperArgs = { - hostIds: Array; + hostIds: Array; }; export type MutationRestartTaskArgs = { - failedOnly: Scalars["Boolean"]; - taskId: Scalars["String"]; + failedOnly: Scalars["Boolean"]["input"]; + taskId: Scalars["String"]["input"]; }; export type MutationRestartVersionsArgs = { - abort: Scalars["Boolean"]; - versionId: Scalars["String"]; + abort: Scalars["Boolean"]["input"]; + versionId: Scalars["String"]["input"]; versionsToRestart: Array; }; @@ -1193,40 +1234,40 @@ export type MutationSaveSubscriptionArgs = { export type MutationSchedulePatchArgs = { configure: PatchConfigure; - patchId: Scalars["String"]; + patchId: Scalars["String"]["input"]; }; export type MutationSchedulePatchTasksArgs = { - patchId: Scalars["String"]; + patchId: Scalars["String"]["input"]; }; export type MutationScheduleTasksArgs = { - taskIds: Array; + taskIds: Array; }; export type MutationScheduleUndispatchedBaseTasksArgs = { - patchId: Scalars["String"]; + patchId: Scalars["String"]["input"]; }; export type MutationSetAnnotationMetadataLinksArgs = { - execution: Scalars["Int"]; + execution: Scalars["Int"]["input"]; metadataLinks: Array; - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }; export type MutationSetPatchPriorityArgs = { - patchId: Scalars["String"]; - priority: Scalars["Int"]; + patchId: Scalars["String"]["input"]; + priority: Scalars["Int"]["input"]; }; export type MutationSetPatchVisibilityArgs = { - hidden: Scalars["Boolean"]; - patchIds: Array; + hidden: Scalars["Boolean"]["input"]; + patchIds: Array; }; export type MutationSetTaskPriorityArgs = { - priority: Scalars["Int"]; - taskId: Scalars["String"]; + priority: Scalars["Int"]["input"]; + taskId: Scalars["String"]["input"]; }; export type MutationSpawnHostArgs = { @@ -1238,28 +1279,28 @@ export type MutationSpawnVolumeArgs = { }; export type MutationUnschedulePatchTasksArgs = { - abort: Scalars["Boolean"]; - patchId: Scalars["String"]; + abort: Scalars["Boolean"]["input"]; + patchId: Scalars["String"]["input"]; }; export type MutationUnscheduleTaskArgs = { - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }; export type MutationUpdateHostStatusArgs = { - hostIds: Array; - notes?: InputMaybe; - status: Scalars["String"]; + hostIds: Array; + notes?: InputMaybe; + status: Scalars["String"]["input"]; }; export type MutationUpdatePublicKeyArgs = { - targetKeyName: Scalars["String"]; + targetKeyName: Scalars["String"]["input"]; updateInfo: PublicKeyInput; }; export type MutationUpdateSpawnHostStatusArgs = { action: SpawnHostStatusActions; - hostId: Scalars["String"]; + hostId: Scalars["String"]["input"]; }; export type MutationUpdateUserSettingsArgs = { @@ -1273,103 +1314,109 @@ export type MutationUpdateVolumeArgs = { /** Return type representing whether a distro was created and any validation errors */ export type NewDistroPayload = { __typename?: "NewDistroPayload"; - newDistroId: Scalars["String"]; + newDistroId: Scalars["String"]["output"]; }; export type Note = { __typename?: "Note"; - message: Scalars["String"]; + message: Scalars["String"]["output"]; source: Source; }; export type Notifications = { __typename?: "Notifications"; - buildBreak?: Maybe; - buildBreakId?: Maybe; - commitQueue?: Maybe; - commitQueueId?: Maybe; - patchFinish?: Maybe; - patchFinishId?: Maybe; - patchFirstFailure?: Maybe; - patchFirstFailureId?: Maybe; - spawnHostExpiration?: Maybe; - spawnHostExpirationId?: Maybe; - spawnHostOutcome?: Maybe; - spawnHostOutcomeId?: Maybe; + buildBreak?: Maybe; + buildBreakId?: Maybe; + commitQueue?: Maybe; + commitQueueId?: Maybe; + patchFinish?: Maybe; + patchFinishId?: Maybe; + patchFirstFailure?: Maybe; + patchFirstFailureId?: Maybe; + spawnHostExpiration?: Maybe; + spawnHostExpirationId?: Maybe; + spawnHostOutcome?: Maybe; + spawnHostOutcomeId?: Maybe; }; export type NotificationsInput = { - buildBreak?: InputMaybe; - commitQueue?: InputMaybe; - patchFinish?: InputMaybe; - patchFirstFailure?: InputMaybe; - spawnHostExpiration?: InputMaybe; - spawnHostOutcome?: InputMaybe; + buildBreak?: InputMaybe; + commitQueue?: InputMaybe; + patchFinish?: InputMaybe; + patchFirstFailure?: InputMaybe; + spawnHostExpiration?: InputMaybe; + spawnHostOutcome?: InputMaybe; }; export type OomTrackerInfo = { __typename?: "OomTrackerInfo"; - detected: Scalars["Boolean"]; - pids?: Maybe>>; + detected: Scalars["Boolean"]["output"]; + pids?: Maybe>>; }; +export enum OverallocatedRule { + Default = "DEFAULT", + Ignore = "IGNORE", + Terminate = "TERMINATE", +} + export type Parameter = { __typename?: "Parameter"; - key: Scalars["String"]; - value: Scalars["String"]; + key: Scalars["String"]["output"]; + value: Scalars["String"]["output"]; }; export type ParameterInput = { - key: Scalars["String"]; - value: Scalars["String"]; + key: Scalars["String"]["input"]; + value: Scalars["String"]["input"]; }; export type ParsleyFilter = { __typename?: "ParsleyFilter"; - caseSensitive: Scalars["Boolean"]; - exactMatch: Scalars["Boolean"]; - expression: Scalars["String"]; + caseSensitive: Scalars["Boolean"]["output"]; + exactMatch: Scalars["Boolean"]["output"]; + expression: Scalars["String"]["output"]; }; export type ParsleyFilterInput = { - caseSensitive: Scalars["Boolean"]; - exactMatch: Scalars["Boolean"]; - expression: Scalars["String"]; + caseSensitive: Scalars["Boolean"]["input"]; + exactMatch: Scalars["Boolean"]["input"]; + expression: Scalars["String"]["input"]; }; /** Patch is a manually initiated version submitted to test local code changes. */ export type Patch = { __typename?: "Patch"; - activated: Scalars["Boolean"]; - alias?: Maybe; - author: Scalars["String"]; - authorDisplayName: Scalars["String"]; - baseTaskStatuses: Array; + activated: Scalars["Boolean"]["output"]; + alias?: Maybe; + author: Scalars["String"]["output"]; + authorDisplayName: Scalars["String"]["output"]; + baseTaskStatuses: Array; builds: Array; - canEnqueueToCommitQueue: Scalars["Boolean"]; + canEnqueueToCommitQueue: Scalars["Boolean"]["output"]; childPatchAliases?: Maybe>; childPatches?: Maybe>; - commitQueuePosition?: Maybe; - createTime?: Maybe; - description: Scalars["String"]; + commitQueuePosition?: Maybe; + createTime?: Maybe; + description: Scalars["String"]["output"]; duration?: Maybe; - githash: Scalars["String"]; - hidden: Scalars["Boolean"]; - id: Scalars["ID"]; + githash: Scalars["String"]["output"]; + hidden: Scalars["Boolean"]["output"]; + id: Scalars["ID"]["output"]; moduleCodeChanges: Array; parameters: Array; - patchNumber: Scalars["Int"]; + patchNumber: Scalars["Int"]["output"]; patchTriggerAliases: Array; project?: Maybe; - projectID: Scalars["String"]; - projectIdentifier: Scalars["String"]; + projectID: Scalars["String"]["output"]; + projectIdentifier: Scalars["String"]["output"]; projectMetadata?: Maybe; - status: Scalars["String"]; - taskCount?: Maybe; - taskStatuses: Array; - tasks: Array; + status: Scalars["String"]["output"]; + taskCount?: Maybe; + taskStatuses: Array; + tasks: Array; time?: Maybe; - variants: Array; + variants: Array; variantsTasks: Array>; versionFull?: Maybe; }; @@ -1379,17 +1426,17 @@ export type Patch = { * It contains information about how a user has configured their patch (e.g. name, tasks to run, etc). */ export type PatchConfigure = { - description: Scalars["String"]; + description: Scalars["String"]["input"]; parameters?: InputMaybe>>; - patchTriggerAliases?: InputMaybe>; + patchTriggerAliases?: InputMaybe>; variantsTasks: Array; }; export type PatchDuration = { __typename?: "PatchDuration"; - makespan?: Maybe; + makespan?: Maybe; time?: Maybe; - timeTaken?: Maybe; + timeTaken?: Maybe; }; export type PatchProject = { @@ -1399,27 +1446,27 @@ export type PatchProject = { export type PatchTime = { __typename?: "PatchTime"; - finished?: Maybe; - started?: Maybe; - submittedAt: Scalars["String"]; + finished?: Maybe; + started?: Maybe; + submittedAt: Scalars["String"]["output"]; }; export type PatchTriggerAlias = { __typename?: "PatchTriggerAlias"; - alias: Scalars["String"]; - childProjectId: Scalars["String"]; - childProjectIdentifier: Scalars["String"]; - parentAsModule?: Maybe; - status?: Maybe; + alias: Scalars["String"]["output"]; + childProjectId: Scalars["String"]["output"]; + childProjectIdentifier: Scalars["String"]["output"]; + parentAsModule?: Maybe; + status?: Maybe; taskSpecifiers?: Maybe>; variantsTasks: Array; }; export type PatchTriggerAliasInput = { - alias: Scalars["String"]; - childProjectIdentifier: Scalars["String"]; - parentAsModule?: InputMaybe; - status?: InputMaybe; + alias: Scalars["String"]["input"]; + childProjectIdentifier: Scalars["String"]["input"]; + parentAsModule?: InputMaybe; + status?: InputMaybe; taskSpecifiers: Array; }; @@ -1429,7 +1476,7 @@ export type PatchTriggerAliasInput = { */ export type Patches = { __typename?: "Patches"; - filteredPatchCount: Scalars["Int"]; + filteredPatchCount: Scalars["Int"]["output"]; patches: Array; }; @@ -1438,41 +1485,41 @@ export type Patches = { * Based on the information in PatchesInput, we return a list of Patches for either an individual user or a project. */ export type PatchesInput = { - includeCommitQueue?: InputMaybe; - limit?: Scalars["Int"]; - onlyCommitQueue?: InputMaybe; - page?: Scalars["Int"]; - patchName?: Scalars["String"]; - statuses?: Array; + includeCommitQueue?: InputMaybe; + limit?: Scalars["Int"]["input"]; + onlyCommitQueue?: InputMaybe; + page?: Scalars["Int"]["input"]; + patchName?: Scalars["String"]["input"]; + statuses?: Array; }; export type PeriodicBuild = { __typename?: "PeriodicBuild"; - alias: Scalars["String"]; - configFile: Scalars["String"]; - cron: Scalars["String"]; - id: Scalars["String"]; - intervalHours: Scalars["Int"]; - message: Scalars["String"]; - nextRunTime: Scalars["Time"]; + alias: Scalars["String"]["output"]; + configFile: Scalars["String"]["output"]; + cron: Scalars["String"]["output"]; + id: Scalars["String"]["output"]; + intervalHours: Scalars["Int"]["output"]; + message: Scalars["String"]["output"]; + nextRunTime: Scalars["Time"]["output"]; }; export type PeriodicBuildInput = { - alias: Scalars["String"]; - configFile: Scalars["String"]; - cron?: InputMaybe; - id: Scalars["String"]; - intervalHours: Scalars["Int"]; - message: Scalars["String"]; - nextRunTime: Scalars["Time"]; + alias: Scalars["String"]["input"]; + configFile: Scalars["String"]["input"]; + cron?: InputMaybe; + id: Scalars["String"]["input"]; + intervalHours: Scalars["Int"]["input"]; + message: Scalars["String"]["input"]; + nextRunTime: Scalars["Time"]["input"]; }; export type Permissions = { __typename?: "Permissions"; - canCreateDistro: Scalars["Boolean"]; - canCreateProject: Scalars["Boolean"]; + canCreateDistro: Scalars["Boolean"]["output"]; + canCreateProject: Scalars["Boolean"]["output"]; distroPermissions: DistroPermissions; - userId: Scalars["String"]; + userId: Scalars["String"]["output"]; }; export type PermissionsDistroPermissionsArgs = { @@ -1481,26 +1528,26 @@ export type PermissionsDistroPermissionsArgs = { export type PlannerSettings = { __typename?: "PlannerSettings"; - commitQueueFactor: Scalars["Int"]; - expectedRuntimeFactor: Scalars["Int"]; - generateTaskFactor: Scalars["Int"]; - groupVersions: Scalars["Boolean"]; - mainlineTimeInQueueFactor: Scalars["Int"]; - patchFactor: Scalars["Int"]; - patchTimeInQueueFactor: Scalars["Int"]; - targetTime: Scalars["Duration"]; + commitQueueFactor: Scalars["Int"]["output"]; + expectedRuntimeFactor: Scalars["Int"]["output"]; + generateTaskFactor: Scalars["Int"]["output"]; + groupVersions: Scalars["Boolean"]["output"]; + mainlineTimeInQueueFactor: Scalars["Int"]["output"]; + patchFactor: Scalars["Int"]["output"]; + patchTimeInQueueFactor: Scalars["Int"]["output"]; + targetTime: Scalars["Duration"]["output"]; version: PlannerVersion; }; export type PlannerSettingsInput = { - commitQueueFactor: Scalars["Int"]; - expectedRuntimeFactor: Scalars["Int"]; - generateTaskFactor: Scalars["Int"]; - groupVersions: Scalars["Boolean"]; - mainlineTimeInQueueFactor: Scalars["Int"]; - patchFactor: Scalars["Int"]; - patchTimeInQueueFactor: Scalars["Int"]; - targetTime: Scalars["Int"]; + commitQueueFactor: Scalars["Int"]["input"]; + expectedRuntimeFactor: Scalars["Int"]["input"]; + generateTaskFactor: Scalars["Int"]["input"]; + groupVersions: Scalars["Boolean"]["input"]; + mainlineTimeInQueueFactor: Scalars["Int"]["input"]; + patchFactor: Scalars["Int"]["input"]; + patchTimeInQueueFactor: Scalars["Int"]["input"]; + targetTime: Scalars["Int"]["input"]; version: PlannerVersion; }; @@ -1512,38 +1559,38 @@ export enum PlannerVersion { export type Pod = { __typename?: "Pod"; events: PodEvents; - id: Scalars["String"]; - status: Scalars["String"]; + id: Scalars["String"]["output"]; + status: Scalars["String"]["output"]; task?: Maybe; taskContainerCreationOpts: TaskContainerCreationOpts; - type: Scalars["String"]; + type: Scalars["String"]["output"]; }; export type PodEventsArgs = { - limit?: InputMaybe; - page?: InputMaybe; + limit?: InputMaybe; + page?: InputMaybe; }; export type PodEventLogData = { __typename?: "PodEventLogData"; - newStatus?: Maybe; - oldStatus?: Maybe; - reason?: Maybe; + newStatus?: Maybe; + oldStatus?: Maybe; + reason?: Maybe; task?: Maybe; - taskExecution?: Maybe; - taskID?: Maybe; - taskStatus?: Maybe; + taskExecution?: Maybe; + taskID?: Maybe; + taskStatus?: Maybe; }; export type PodEventLogEntry = { __typename?: "PodEventLogEntry"; data: PodEventLogData; - eventType?: Maybe; - id: Scalars["String"]; - processedAt: Scalars["Time"]; - resourceId: Scalars["String"]; - resourceType: Scalars["String"]; - timestamp?: Maybe; + eventType?: Maybe; + id: Scalars["String"]["output"]; + processedAt: Scalars["Time"]["output"]; + resourceId: Scalars["String"]["output"]; + resourceType: Scalars["String"]["output"]; + timestamp?: Maybe; }; /** @@ -1552,70 +1599,70 @@ export type PodEventLogEntry = { */ export type PodEvents = { __typename?: "PodEvents"; - count: Scalars["Int"]; + count: Scalars["Int"]["output"]; eventLogEntries: Array; }; export type PreconditionScript = { __typename?: "PreconditionScript"; - path: Scalars["String"]; - script: Scalars["String"]; + path: Scalars["String"]["output"]; + script: Scalars["String"]["output"]; }; export type PreconditionScriptInput = { - path: Scalars["String"]; - script: Scalars["String"]; + path: Scalars["String"]["input"]; + script: Scalars["String"]["input"]; }; /** Project models single repository on GitHub. */ export type Project = { __typename?: "Project"; - admins?: Maybe>>; + admins?: Maybe>>; banner?: Maybe; - batchTime: Scalars["Int"]; - branch: Scalars["String"]; + batchTime: Scalars["Int"]["output"]; + branch: Scalars["String"]["output"]; buildBaronSettings: BuildBaronSettings; commitQueue: CommitQueueParams; containerSizeDefinitions?: Maybe>; - deactivatePrevious?: Maybe; - disabledStatsCache?: Maybe; - dispatchingDisabled?: Maybe; - displayName: Scalars["String"]; - enabled?: Maybe; + deactivatePrevious?: Maybe; + disabledStatsCache?: Maybe; + dispatchingDisabled?: Maybe; + displayName: Scalars["String"]["output"]; + enabled?: Maybe; externalLinks?: Maybe>; - gitTagAuthorizedTeams?: Maybe>; - gitTagAuthorizedUsers?: Maybe>; - gitTagVersionsEnabled?: Maybe; - githubChecksEnabled?: Maybe; - githubTriggerAliases?: Maybe>; - hidden?: Maybe; - id: Scalars["String"]; - identifier: Scalars["String"]; - isFavorite: Scalars["Boolean"]; - manualPrTestingEnabled?: Maybe; - notifyOnBuildFailure?: Maybe; - owner: Scalars["String"]; + gitTagAuthorizedTeams?: Maybe>; + gitTagAuthorizedUsers?: Maybe>; + gitTagVersionsEnabled?: Maybe; + githubChecksEnabled?: Maybe; + githubTriggerAliases?: Maybe>; + hidden?: Maybe; + id: Scalars["String"]["output"]; + identifier: Scalars["String"]["output"]; + isFavorite: Scalars["Boolean"]["output"]; + manualPrTestingEnabled?: Maybe; + notifyOnBuildFailure?: Maybe; + owner: Scalars["String"]["output"]; parsleyFilters?: Maybe>; patchTriggerAliases?: Maybe>; patches: Patches; - patchingDisabled?: Maybe; - perfEnabled?: Maybe; + patchingDisabled?: Maybe; + perfEnabled?: Maybe; periodicBuilds?: Maybe>; - prTestingEnabled?: Maybe; - private?: Maybe; + prTestingEnabled?: Maybe; + private?: Maybe; projectHealthView: ProjectHealthView; - remotePath: Scalars["String"]; - repo: Scalars["String"]; - repoRefId: Scalars["String"]; - repotrackerDisabled?: Maybe; - restricted?: Maybe; - spawnHostScriptPath: Scalars["String"]; - stepbackDisabled?: Maybe; + remotePath: Scalars["String"]["output"]; + repo: Scalars["String"]["output"]; + repoRefId: Scalars["String"]["output"]; + repotrackerDisabled?: Maybe; + restricted?: Maybe; + spawnHostScriptPath: Scalars["String"]["output"]; + stepbackDisabled?: Maybe; taskAnnotationSettings: TaskAnnotationSettings; taskSync: TaskSyncOptions; - tracksPushEvents?: Maybe; + tracksPushEvents?: Maybe; triggers?: Maybe>; - versionControlEnabled?: Maybe; + versionControlEnabled?: Maybe; workstationConfig: WorkstationConfig; }; @@ -1626,61 +1673,61 @@ export type ProjectPatchesArgs = { export type ProjectAlias = { __typename?: "ProjectAlias"; - alias: Scalars["String"]; - description?: Maybe; - gitTag: Scalars["String"]; - id: Scalars["String"]; + alias: Scalars["String"]["output"]; + description?: Maybe; + gitTag: Scalars["String"]["output"]; + id: Scalars["String"]["output"]; parameters: Array; - remotePath: Scalars["String"]; - task: Scalars["String"]; - taskTags: Array; - variant: Scalars["String"]; - variantTags: Array; + remotePath: Scalars["String"]["output"]; + task: Scalars["String"]["output"]; + taskTags: Array; + variant: Scalars["String"]["output"]; + variantTags: Array; }; export type ProjectAliasInput = { - alias: Scalars["String"]; - description?: InputMaybe; - gitTag: Scalars["String"]; - id: Scalars["String"]; + alias: Scalars["String"]["input"]; + description?: InputMaybe; + gitTag: Scalars["String"]["input"]; + id: Scalars["String"]["input"]; parameters?: InputMaybe>; - remotePath: Scalars["String"]; - task: Scalars["String"]; - taskTags: Array; - variant: Scalars["String"]; - variantTags: Array; + remotePath: Scalars["String"]["input"]; + task: Scalars["String"]["input"]; + taskTags: Array; + variant: Scalars["String"]["input"]; + variantTags: Array; }; export type ProjectBanner = { __typename?: "ProjectBanner"; - text: Scalars["String"]; + text: Scalars["String"]["output"]; theme: BannerTheme; }; export type ProjectBannerInput = { - text: Scalars["String"]; + text: Scalars["String"]["input"]; theme: BannerTheme; }; export type ProjectBuildVariant = { __typename?: "ProjectBuildVariant"; - displayName: Scalars["String"]; - name: Scalars["String"]; - tasks: Array; + displayName: Scalars["String"]["output"]; + name: Scalars["String"]["output"]; + tasks: Array; }; export type ProjectEventLogEntry = { __typename?: "ProjectEventLogEntry"; after?: Maybe; before?: Maybe; - timestamp: Scalars["Time"]; - user: Scalars["String"]; + timestamp: Scalars["Time"]["output"]; + user: Scalars["String"]["output"]; }; export type ProjectEventSettings = { __typename?: "ProjectEventSettings"; aliases?: Maybe>; - githubWebhooksEnabled: Scalars["Boolean"]; + githubWebhooksEnabled: Scalars["Boolean"]["output"]; projectRef?: Maybe; subscriptions?: Maybe>; vars?: Maybe; @@ -1694,7 +1741,7 @@ export type ProjectEventSettings = { */ export type ProjectEvents = { __typename?: "ProjectEvents"; - count: Scalars["Int"]; + count: Scalars["Int"]["output"]; eventLogEntries: Array; }; @@ -1704,48 +1751,50 @@ export enum ProjectHealthView { } export type ProjectInput = { - admins?: InputMaybe>; + admins?: InputMaybe>; banner?: InputMaybe; - batchTime?: InputMaybe; - branch?: InputMaybe; + batchTime?: InputMaybe; + branch?: InputMaybe; buildBaronSettings?: InputMaybe; commitQueue?: InputMaybe; containerSizeDefinitions?: InputMaybe>; - deactivatePrevious?: InputMaybe; - disabledStatsCache?: InputMaybe; - dispatchingDisabled?: InputMaybe; - displayName?: InputMaybe; - enabled?: InputMaybe; + deactivatePrevious?: InputMaybe; + disabledStatsCache?: InputMaybe; + dispatchingDisabled?: InputMaybe; + displayName?: InputMaybe; + enabled?: InputMaybe; externalLinks?: InputMaybe>; - gitTagAuthorizedTeams?: InputMaybe>; - gitTagAuthorizedUsers?: InputMaybe>; - gitTagVersionsEnabled?: InputMaybe; - githubChecksEnabled?: InputMaybe; - githubTriggerAliases?: InputMaybe>>; - id: Scalars["String"]; - identifier?: InputMaybe; - manualPrTestingEnabled?: InputMaybe; - notifyOnBuildFailure?: InputMaybe; - owner?: InputMaybe; + gitTagAuthorizedTeams?: InputMaybe>; + gitTagAuthorizedUsers?: InputMaybe>; + gitTagVersionsEnabled?: InputMaybe; + githubChecksEnabled?: InputMaybe; + githubTriggerAliases?: InputMaybe< + Array> + >; + id: Scalars["String"]["input"]; + identifier?: InputMaybe; + manualPrTestingEnabled?: InputMaybe; + notifyOnBuildFailure?: InputMaybe; + owner?: InputMaybe; parsleyFilters?: InputMaybe>; patchTriggerAliases?: InputMaybe>; - patchingDisabled?: InputMaybe; - perfEnabled?: InputMaybe; + patchingDisabled?: InputMaybe; + perfEnabled?: InputMaybe; periodicBuilds?: InputMaybe>; - prTestingEnabled?: InputMaybe; - private?: InputMaybe; + prTestingEnabled?: InputMaybe; + private?: InputMaybe; projectHealthView?: InputMaybe; - remotePath?: InputMaybe; - repo?: InputMaybe; - repotrackerDisabled?: InputMaybe; - restricted?: InputMaybe; - spawnHostScriptPath?: InputMaybe; - stepbackDisabled?: InputMaybe; + remotePath?: InputMaybe; + repo?: InputMaybe; + repotrackerDisabled?: InputMaybe; + restricted?: InputMaybe; + spawnHostScriptPath?: InputMaybe; + stepbackDisabled?: InputMaybe; taskAnnotationSettings?: InputMaybe; taskSync?: InputMaybe; - tracksPushEvents?: InputMaybe; + tracksPushEvents?: InputMaybe; triggers?: InputMaybe>; - versionControlEnabled?: InputMaybe; + versionControlEnabled?: InputMaybe; workstationConfig?: InputMaybe; }; @@ -1753,7 +1802,7 @@ export type ProjectInput = { export type ProjectSettings = { __typename?: "ProjectSettings"; aliases?: Maybe>; - githubWebhooksEnabled: Scalars["Boolean"]; + githubWebhooksEnabled: Scalars["Boolean"]["output"]; projectRef?: Maybe; subscriptions?: Maybe>; vars?: Maybe; @@ -1771,7 +1820,7 @@ export enum ProjectSettingsAccess { */ export type ProjectSettingsInput = { aliases?: InputMaybe>; - githubWebhooksEnabled?: InputMaybe; + githubWebhooksEnabled?: InputMaybe; projectRef?: InputMaybe; subscriptions?: InputMaybe>; vars?: InputMaybe; @@ -1794,33 +1843,40 @@ export enum ProjectSettingsSection { export type ProjectVars = { __typename?: "ProjectVars"; - adminOnlyVars: Array; - privateVars: Array; - vars?: Maybe; + adminOnlyVars: Array; + privateVars: Array; + vars?: Maybe; }; export type ProjectVarsInput = { - adminOnlyVarsList?: InputMaybe>>; - privateVarsList?: InputMaybe>>; - vars?: InputMaybe; + adminOnlyVarsList?: InputMaybe>>; + privateVarsList?: InputMaybe>>; + vars?: InputMaybe; }; +export enum Provider { + Docker = "DOCKER", + Ec2Fleet = "EC2_FLEET", + Ec2OnDemand = "EC2_ON_DEMAND", + Static = "STATIC", +} + /** PublicKey models a public key. Users can save/modify/delete their public keys. */ export type PublicKey = { __typename?: "PublicKey"; - key: Scalars["String"]; - name: Scalars["String"]; + key: Scalars["String"]["output"]; + name: Scalars["String"]["output"]; }; /** PublicKeyInput is an input to the createPublicKey and updatePublicKey mutations. */ export type PublicKeyInput = { - key: Scalars["String"]; - name: Scalars["String"]; + key: Scalars["String"]["input"]; + name: Scalars["String"]["input"]; }; export type Query = { __typename?: "Query"; - awsRegions?: Maybe>; + awsRegions?: Maybe>; bbGetCreatedTickets: Array; buildBaron: BuildBaron; buildVariantsForTaskName?: Maybe>>; @@ -1831,11 +1887,11 @@ export type Query = { distroTaskQueue: Array; distros: Array>; githubProjectConflicts: GithubProjectConflicts; - hasVersion: Scalars["Boolean"]; + hasVersion: Scalars["Boolean"]["output"]; host?: Maybe; hostEvents: HostEvents; hosts: HostsResponse; - instanceTypes: Array; + instanceTypes: Array; logkeeperBuildMetadata: LogkeeperBuild; mainlineCommits?: Maybe; myHosts: Array; @@ -1850,10 +1906,10 @@ export type Query = { repoEvents: ProjectEvents; repoSettings: RepoSettings; spruceConfig?: Maybe; - subnetAvailabilityZones: Array; + subnetAvailabilityZones: Array; task?: Maybe; taskAllExecutions: Array; - taskNamesForBuildVariant?: Maybe>; + taskNamesForBuildVariant?: Maybe>; taskQueueDistros: Array; taskTestSample?: Maybe>; user: User; @@ -1864,25 +1920,25 @@ export type Query = { }; export type QueryBbGetCreatedTicketsArgs = { - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }; export type QueryBuildBaronArgs = { - execution: Scalars["Int"]; - taskId: Scalars["String"]; + execution: Scalars["Int"]["input"]; + taskId: Scalars["String"]["input"]; }; export type QueryBuildVariantsForTaskNameArgs = { - projectIdentifier: Scalars["String"]; - taskName: Scalars["String"]; + projectIdentifier: Scalars["String"]["input"]; + taskName: Scalars["String"]["input"]; }; export type QueryCommitQueueArgs = { - projectIdentifier: Scalars["String"]; + projectIdentifier: Scalars["String"]["input"]; }; export type QueryDistroArgs = { - distroId: Scalars["String"]; + distroId: Scalars["String"]["input"]; }; export type QueryDistroEventsArgs = { @@ -1890,46 +1946,46 @@ export type QueryDistroEventsArgs = { }; export type QueryDistroTaskQueueArgs = { - distroId: Scalars["String"]; + distroId: Scalars["String"]["input"]; }; export type QueryDistrosArgs = { - onlySpawnable: Scalars["Boolean"]; + onlySpawnable: Scalars["Boolean"]["input"]; }; export type QueryGithubProjectConflictsArgs = { - projectId: Scalars["String"]; + projectId: Scalars["String"]["input"]; }; export type QueryHasVersionArgs = { - id: Scalars["String"]; + id: Scalars["String"]["input"]; }; export type QueryHostArgs = { - hostId: Scalars["String"]; + hostId: Scalars["String"]["input"]; }; export type QueryHostEventsArgs = { - hostId: Scalars["String"]; - hostTag?: InputMaybe; - limit?: InputMaybe; - page?: InputMaybe; + hostId: Scalars["String"]["input"]; + hostTag?: InputMaybe; + limit?: InputMaybe; + page?: InputMaybe; }; export type QueryHostsArgs = { - currentTaskId?: InputMaybe; - distroId?: InputMaybe; - hostId?: InputMaybe; - limit?: InputMaybe; - page?: InputMaybe; + currentTaskId?: InputMaybe; + distroId?: InputMaybe; + hostId?: InputMaybe; + limit?: InputMaybe; + page?: InputMaybe; sortBy?: InputMaybe; sortDir?: InputMaybe; - startedBy?: InputMaybe; - statuses?: InputMaybe>; + startedBy?: InputMaybe; + statuses?: InputMaybe>; }; export type QueryLogkeeperBuildMetadataArgs = { - buildId: Scalars["String"]; + buildId: Scalars["String"]["input"]; }; export type QueryMainlineCommitsArgs = { @@ -1938,70 +1994,70 @@ export type QueryMainlineCommitsArgs = { }; export type QueryPatchArgs = { - id: Scalars["String"]; + id: Scalars["String"]["input"]; }; export type QueryPodArgs = { - podId: Scalars["String"]; + podId: Scalars["String"]["input"]; }; export type QueryProjectArgs = { - projectIdentifier: Scalars["String"]; + projectIdentifier: Scalars["String"]["input"]; }; export type QueryProjectEventsArgs = { - before?: InputMaybe; - identifier: Scalars["String"]; - limit?: InputMaybe; + before?: InputMaybe; + identifier: Scalars["String"]["input"]; + limit?: InputMaybe; }; export type QueryProjectSettingsArgs = { - identifier: Scalars["String"]; + identifier: Scalars["String"]["input"]; }; export type QueryRepoEventsArgs = { - before?: InputMaybe; - id: Scalars["String"]; - limit?: InputMaybe; + before?: InputMaybe; + id: Scalars["String"]["input"]; + limit?: InputMaybe; }; export type QueryRepoSettingsArgs = { - id: Scalars["String"]; + id: Scalars["String"]["input"]; }; export type QueryTaskArgs = { - execution?: InputMaybe; - taskId: Scalars["String"]; + execution?: InputMaybe; + taskId: Scalars["String"]["input"]; }; export type QueryTaskAllExecutionsArgs = { - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }; export type QueryTaskNamesForBuildVariantArgs = { - buildVariant: Scalars["String"]; - projectIdentifier: Scalars["String"]; + buildVariant: Scalars["String"]["input"]; + projectIdentifier: Scalars["String"]["input"]; }; export type QueryTaskTestSampleArgs = { filters: Array; - tasks: Array; + tasks: Array; }; export type QueryUserArgs = { - userId?: InputMaybe; + userId?: InputMaybe; }; export type QueryVersionArgs = { - id: Scalars["String"]; + id: Scalars["String"]["input"]; }; export type RepoCommitQueueParams = { __typename?: "RepoCommitQueueParams"; - enabled: Scalars["Boolean"]; - mergeMethod: Scalars["String"]; + enabled: Scalars["Boolean"]["output"]; + mergeMethod: Scalars["String"]["output"]; mergeQueue: MergeQueue; - message: Scalars["String"]; + message: Scalars["String"]["output"]; }; /** @@ -2011,84 +2067,84 @@ export type RepoCommitQueueParams = { */ export type RepoRef = { __typename?: "RepoRef"; - admins: Array; - batchTime: Scalars["Int"]; + admins: Array; + batchTime: Scalars["Int"]["output"]; buildBaronSettings: BuildBaronSettings; commitQueue: RepoCommitQueueParams; containerSizeDefinitions?: Maybe>; - deactivatePrevious: Scalars["Boolean"]; - disabledStatsCache: Scalars["Boolean"]; - dispatchingDisabled: Scalars["Boolean"]; - displayName: Scalars["String"]; - enabled: Scalars["Boolean"]; + deactivatePrevious: Scalars["Boolean"]["output"]; + disabledStatsCache: Scalars["Boolean"]["output"]; + dispatchingDisabled: Scalars["Boolean"]["output"]; + displayName: Scalars["String"]["output"]; + enabled: Scalars["Boolean"]["output"]; externalLinks?: Maybe>; - gitTagAuthorizedTeams?: Maybe>; - gitTagAuthorizedUsers?: Maybe>; - gitTagVersionsEnabled: Scalars["Boolean"]; - githubChecksEnabled: Scalars["Boolean"]; - githubTriggerAliases?: Maybe>; - id: Scalars["String"]; - manualPrTestingEnabled: Scalars["Boolean"]; - notifyOnBuildFailure: Scalars["Boolean"]; - owner: Scalars["String"]; + gitTagAuthorizedTeams?: Maybe>; + gitTagAuthorizedUsers?: Maybe>; + gitTagVersionsEnabled: Scalars["Boolean"]["output"]; + githubChecksEnabled: Scalars["Boolean"]["output"]; + githubTriggerAliases?: Maybe>; + id: Scalars["String"]["output"]; + manualPrTestingEnabled: Scalars["Boolean"]["output"]; + notifyOnBuildFailure: Scalars["Boolean"]["output"]; + owner: Scalars["String"]["output"]; patchTriggerAliases?: Maybe>; - patchingDisabled: Scalars["Boolean"]; - perfEnabled: Scalars["Boolean"]; + patchingDisabled: Scalars["Boolean"]["output"]; + perfEnabled: Scalars["Boolean"]["output"]; periodicBuilds?: Maybe>; - prTestingEnabled: Scalars["Boolean"]; - private: Scalars["Boolean"]; - remotePath: Scalars["String"]; - repo: Scalars["String"]; - repotrackerDisabled: Scalars["Boolean"]; - restricted: Scalars["Boolean"]; - spawnHostScriptPath: Scalars["String"]; - stepbackDisabled: Scalars["Boolean"]; + prTestingEnabled: Scalars["Boolean"]["output"]; + private: Scalars["Boolean"]["output"]; + remotePath: Scalars["String"]["output"]; + repo: Scalars["String"]["output"]; + repotrackerDisabled: Scalars["Boolean"]["output"]; + restricted: Scalars["Boolean"]["output"]; + spawnHostScriptPath: Scalars["String"]["output"]; + stepbackDisabled: Scalars["Boolean"]["output"]; taskAnnotationSettings: TaskAnnotationSettings; taskSync: RepoTaskSyncOptions; - tracksPushEvents: Scalars["Boolean"]; + tracksPushEvents: Scalars["Boolean"]["output"]; triggers: Array; - versionControlEnabled: Scalars["Boolean"]; + versionControlEnabled: Scalars["Boolean"]["output"]; workstationConfig: RepoWorkstationConfig; }; export type RepoRefInput = { - admins?: InputMaybe>; - batchTime?: InputMaybe; + admins?: InputMaybe>; + batchTime?: InputMaybe; buildBaronSettings?: InputMaybe; commitQueue?: InputMaybe; containerSizeDefinitions?: InputMaybe>; - deactivatePrevious?: InputMaybe; - disabledStatsCache?: InputMaybe; - dispatchingDisabled?: InputMaybe; - displayName?: InputMaybe; - enabled?: InputMaybe; + deactivatePrevious?: InputMaybe; + disabledStatsCache?: InputMaybe; + dispatchingDisabled?: InputMaybe; + displayName?: InputMaybe; + enabled?: InputMaybe; externalLinks?: InputMaybe>; - gitTagAuthorizedTeams?: InputMaybe>; - gitTagAuthorizedUsers?: InputMaybe>; - gitTagVersionsEnabled?: InputMaybe; - githubChecksEnabled?: InputMaybe; - githubTriggerAliases?: InputMaybe>; - id: Scalars["String"]; - manualPrTestingEnabled?: InputMaybe; - notifyOnBuildFailure?: InputMaybe; - owner?: InputMaybe; + gitTagAuthorizedTeams?: InputMaybe>; + gitTagAuthorizedUsers?: InputMaybe>; + gitTagVersionsEnabled?: InputMaybe; + githubChecksEnabled?: InputMaybe; + githubTriggerAliases?: InputMaybe>; + id: Scalars["String"]["input"]; + manualPrTestingEnabled?: InputMaybe; + notifyOnBuildFailure?: InputMaybe; + owner?: InputMaybe; patchTriggerAliases?: InputMaybe>; - patchingDisabled?: InputMaybe; - perfEnabled?: InputMaybe; + patchingDisabled?: InputMaybe; + perfEnabled?: InputMaybe; periodicBuilds?: InputMaybe>; - prTestingEnabled?: InputMaybe; - private?: InputMaybe; - remotePath?: InputMaybe; - repo?: InputMaybe; - repotrackerDisabled?: InputMaybe; - restricted?: InputMaybe; - spawnHostScriptPath?: InputMaybe; - stepbackDisabled?: InputMaybe; + prTestingEnabled?: InputMaybe; + private?: InputMaybe; + remotePath?: InputMaybe; + repo?: InputMaybe; + repotrackerDisabled?: InputMaybe; + restricted?: InputMaybe; + spawnHostScriptPath?: InputMaybe; + stepbackDisabled?: InputMaybe; taskAnnotationSettings?: InputMaybe; taskSync?: InputMaybe; - tracksPushEvents?: InputMaybe; + tracksPushEvents?: InputMaybe; triggers?: InputMaybe>; - versionControlEnabled?: InputMaybe; + versionControlEnabled?: InputMaybe; workstationConfig?: InputMaybe; }; @@ -2096,7 +2152,7 @@ export type RepoRefInput = { export type RepoSettings = { __typename?: "RepoSettings"; aliases?: Maybe>; - githubWebhooksEnabled: Scalars["Boolean"]; + githubWebhooksEnabled: Scalars["Boolean"]["output"]; projectRef?: Maybe; subscriptions?: Maybe>; vars?: Maybe; @@ -2109,7 +2165,7 @@ export type RepoSettings = { */ export type RepoSettingsInput = { aliases?: InputMaybe>; - githubWebhooksEnabled?: InputMaybe; + githubWebhooksEnabled?: InputMaybe; projectRef?: InputMaybe; subscriptions?: InputMaybe>; vars?: InputMaybe; @@ -2117,13 +2173,13 @@ export type RepoSettingsInput = { export type RepoTaskSyncOptions = { __typename?: "RepoTaskSyncOptions"; - configEnabled: Scalars["Boolean"]; - patchEnabled: Scalars["Boolean"]; + configEnabled: Scalars["Boolean"]["output"]; + patchEnabled: Scalars["Boolean"]["output"]; }; export type RepoWorkstationConfig = { __typename?: "RepoWorkstationConfig"; - gitClone: Scalars["Boolean"]; + gitClone: Scalars["Boolean"]["output"]; setupCommands?: Maybe>; }; @@ -2135,21 +2191,27 @@ export enum RequiredStatus { export type ResourceLimits = { __typename?: "ResourceLimits"; - lockedMemoryKb: Scalars["Int"]; - numFiles: Scalars["Int"]; - numProcesses: Scalars["Int"]; - numTasks: Scalars["Int"]; - virtualMemoryKb: Scalars["Int"]; + lockedMemoryKb: Scalars["Int"]["output"]; + numFiles: Scalars["Int"]["output"]; + numProcesses: Scalars["Int"]["output"]; + numTasks: Scalars["Int"]["output"]; + virtualMemoryKb: Scalars["Int"]["output"]; }; export type ResourceLimitsInput = { - lockedMemoryKb: Scalars["Int"]; - numFiles: Scalars["Int"]; - numProcesses: Scalars["Int"]; - numTasks: Scalars["Int"]; - virtualMemoryKb: Scalars["Int"]; + lockedMemoryKb: Scalars["Int"]["input"]; + numFiles: Scalars["Int"]["input"]; + numProcesses: Scalars["Int"]["input"]; + numTasks: Scalars["Int"]["input"]; + virtualMemoryKb: Scalars["Int"]["input"]; }; +export enum RoundingRule { + Default = "DEFAULT", + Down = "DOWN", + Up = "UP", +} + /** SaveDistroInput is the input to the saveDistro mutation. */ export type SaveDistroInput = { distro: DistroInput; @@ -2160,31 +2222,31 @@ export type SaveDistroInput = { export type SaveDistroPayload = { __typename?: "SaveDistroPayload"; distro: Distro; - hostCount: Scalars["Int"]; + hostCount: Scalars["Int"]["output"]; }; export type SearchReturnInfo = { __typename?: "SearchReturnInfo"; - featuresURL: Scalars["String"]; + featuresURL: Scalars["String"]["output"]; issues: Array; - search: Scalars["String"]; - source: Scalars["String"]; + search: Scalars["String"]["output"]; + source: Scalars["String"]["output"]; }; export type Selector = { __typename?: "Selector"; - data: Scalars["String"]; - type: Scalars["String"]; + data: Scalars["String"]["output"]; + type: Scalars["String"]["output"]; }; export type SelectorInput = { - data: Scalars["String"]; - type: Scalars["String"]; + data: Scalars["String"]["input"]; + type: Scalars["String"]["input"]; }; export type SlackConfig = { __typename?: "SlackConfig"; - name?: Maybe; + name?: Maybe; }; export enum SortDirection { @@ -2200,16 +2262,16 @@ export type SortOrder = { export type Source = { __typename?: "Source"; - author: Scalars["String"]; - requester: Scalars["String"]; - time: Scalars["Time"]; + author: Scalars["String"]["output"]; + requester: Scalars["String"]["output"]; + time: Scalars["Time"]["output"]; }; export type SpawnHostConfig = { __typename?: "SpawnHostConfig"; - spawnHostsPerUser: Scalars["Int"]; - unexpirableHostsPerUser: Scalars["Int"]; - unexpirableVolumesPerUser: Scalars["Int"]; + spawnHostsPerUser: Scalars["Int"]["output"]; + unexpirableHostsPerUser: Scalars["Int"]["output"]; + unexpirableVolumesPerUser: Scalars["Int"]["output"]; }; /** @@ -2217,22 +2279,22 @@ export type SpawnHostConfig = { * Its fields determine the properties of the host that will be spawned. */ export type SpawnHostInput = { - distroId: Scalars["String"]; - expiration?: InputMaybe; - homeVolumeSize?: InputMaybe; - isVirtualWorkStation: Scalars["Boolean"]; - noExpiration: Scalars["Boolean"]; + distroId: Scalars["String"]["input"]; + expiration?: InputMaybe; + homeVolumeSize?: InputMaybe; + isVirtualWorkStation: Scalars["Boolean"]["input"]; + noExpiration: Scalars["Boolean"]["input"]; publicKey: PublicKeyInput; - region: Scalars["String"]; - savePublicKey: Scalars["Boolean"]; - setUpScript?: InputMaybe; - spawnHostsStartedByTask?: InputMaybe; - taskId?: InputMaybe; - taskSync?: InputMaybe; - useProjectSetupScript?: InputMaybe; - useTaskConfig?: InputMaybe; - userDataScript?: InputMaybe; - volumeId?: InputMaybe; + region: Scalars["String"]["input"]; + savePublicKey: Scalars["Boolean"]["input"]; + setUpScript?: InputMaybe; + spawnHostsStartedByTask?: InputMaybe; + taskId?: InputMaybe; + taskSync?: InputMaybe; + useProjectSetupScript?: InputMaybe; + useTaskConfig?: InputMaybe; + userDataScript?: InputMaybe; + volumeId?: InputMaybe; }; export enum SpawnHostStatusActions { @@ -2246,12 +2308,12 @@ export enum SpawnHostStatusActions { * Its fields determine the properties of the volume that will be spawned. */ export type SpawnVolumeInput = { - availabilityZone: Scalars["String"]; - expiration?: InputMaybe; - host?: InputMaybe; - noExpiration?: InputMaybe; - size: Scalars["Int"]; - type: Scalars["String"]; + availabilityZone: Scalars["String"]["input"]; + expiration?: InputMaybe; + host?: InputMaybe; + noExpiration?: InputMaybe; + size: Scalars["Int"]["input"]; + type: Scalars["String"]["input"]; }; /** @@ -2260,9 +2322,9 @@ export type SpawnVolumeInput = { */ export type SpruceConfig = { __typename?: "SpruceConfig"; - banner?: Maybe; - bannerTheme?: Maybe; - githubOrgs: Array; + banner?: Maybe; + bannerTheme?: Maybe; + githubOrgs: Array; jira?: Maybe; providers?: Maybe; slack?: Maybe; @@ -2272,32 +2334,32 @@ export type SpruceConfig = { export type StatusCount = { __typename?: "StatusCount"; - count: Scalars["Int"]; - status: Scalars["String"]; + count: Scalars["Int"]["output"]; + status: Scalars["String"]["output"]; }; export type Subscriber = { __typename?: "Subscriber"; - emailSubscriber?: Maybe; + emailSubscriber?: Maybe; githubCheckSubscriber?: Maybe; githubPRSubscriber?: Maybe; - jiraCommentSubscriber?: Maybe; + jiraCommentSubscriber?: Maybe; jiraIssueSubscriber?: Maybe; - slackSubscriber?: Maybe; + slackSubscriber?: Maybe; webhookSubscriber?: Maybe; }; export type SubscriberInput = { jiraIssueSubscriber?: InputMaybe; - target: Scalars["String"]; - type: Scalars["String"]; + target: Scalars["String"]["input"]; + type: Scalars["String"]["input"]; webhookSubscriber?: InputMaybe; }; export type SubscriberWrapper = { __typename?: "SubscriberWrapper"; subscriber: Subscriber; - type: Scalars["String"]; + type: Scalars["String"]["output"]; }; /** @@ -2306,91 +2368,93 @@ export type SubscriberWrapper = { * can have a subscription to send them a Slack message when a version finishes. */ export type SubscriptionInput = { - id?: InputMaybe; - owner?: InputMaybe; - owner_type?: InputMaybe; + id?: InputMaybe; + owner?: InputMaybe; + owner_type?: InputMaybe; regex_selectors: Array; - resource_type?: InputMaybe; + resource_type?: InputMaybe; selectors: Array; subscriber: SubscriberInput; - trigger?: InputMaybe; - trigger_data: Scalars["StringMap"]; + trigger?: InputMaybe; + trigger_data: Scalars["StringMap"]["input"]; }; /** Task models a task, the simplest unit of execution for Evergreen. */ export type Task = { __typename?: "Task"; abortInfo?: Maybe; - aborted: Scalars["Boolean"]; - activated: Scalars["Boolean"]; - activatedBy?: Maybe; - activatedTime?: Maybe; - ami?: Maybe; + aborted: Scalars["Boolean"]["output"]; + activated: Scalars["Boolean"]["output"]; + activatedBy?: Maybe; + activatedTime?: Maybe; + ami?: Maybe; annotation?: Maybe; - baseStatus?: Maybe; + baseStatus?: Maybe; baseTask?: Maybe; - blocked: Scalars["Boolean"]; - buildId: Scalars["String"]; - buildVariant: Scalars["String"]; - buildVariantDisplayName?: Maybe; - canAbort: Scalars["Boolean"]; - canDisable: Scalars["Boolean"]; - canModifyAnnotation: Scalars["Boolean"]; - canOverrideDependencies: Scalars["Boolean"]; - canRestart: Scalars["Boolean"]; - canSchedule: Scalars["Boolean"]; - canSetPriority: Scalars["Boolean"]; - canSync: Scalars["Boolean"]; - canUnschedule: Scalars["Boolean"]; - containerAllocatedTime?: Maybe; - createTime?: Maybe; + blocked: Scalars["Boolean"]["output"]; + buildId: Scalars["String"]["output"]; + buildVariant: Scalars["String"]["output"]; + buildVariantDisplayName?: Maybe; + canAbort: Scalars["Boolean"]["output"]; + canDisable: Scalars["Boolean"]["output"]; + canModifyAnnotation: Scalars["Boolean"]["output"]; + canOverrideDependencies: Scalars["Boolean"]["output"]; + canRestart: Scalars["Boolean"]["output"]; + canSchedule: Scalars["Boolean"]["output"]; + canSetPriority: Scalars["Boolean"]["output"]; + canSync: Scalars["Boolean"]["output"]; + canUnschedule: Scalars["Boolean"]["output"]; + containerAllocatedTime?: Maybe; + createTime?: Maybe; dependsOn?: Maybe>; details?: Maybe; - dispatchTime?: Maybe; - displayName: Scalars["String"]; - displayOnly?: Maybe; + dispatchTime?: Maybe; + displayName: Scalars["String"]["output"]; + displayOnly?: Maybe; displayTask?: Maybe; - distroId: Scalars["String"]; - estimatedStart?: Maybe; - execution: Scalars["Int"]; - executionTasks?: Maybe>; + distroId: Scalars["String"]["output"]; + estimatedStart?: Maybe; + execution: Scalars["Int"]["output"]; + executionTasks?: Maybe>; executionTasksFull?: Maybe>; - expectedDuration?: Maybe; - failedTestCount: Scalars["Int"]; - finishTime?: Maybe; - generateTask?: Maybe; - generatedBy?: Maybe; - generatedByName?: Maybe; - hostId?: Maybe; - id: Scalars["String"]; - ingestTime?: Maybe; - isPerfPluginEnabled: Scalars["Boolean"]; - latestExecution: Scalars["Int"]; + expectedDuration?: Maybe; + failedTestCount: Scalars["Int"]["output"]; + files: TaskFiles; + finishTime?: Maybe; + generateTask?: Maybe; + generatedBy?: Maybe; + generatedByName?: Maybe; + hostId?: Maybe; + id: Scalars["String"]["output"]; + ingestTime?: Maybe; + isPerfPluginEnabled: Scalars["Boolean"]["output"]; + latestExecution: Scalars["Int"]["output"]; logs: TaskLogLinks; - minQueuePosition: Scalars["Int"]; - order: Scalars["Int"]; + minQueuePosition: Scalars["Int"]["output"]; + order: Scalars["Int"]["output"]; patch?: Maybe; - patchNumber?: Maybe; + patchNumber?: Maybe; pod?: Maybe; - priority?: Maybe; + priority?: Maybe; project?: Maybe; - projectId: Scalars["String"]; - projectIdentifier?: Maybe; - requester: Scalars["String"]; - resetWhenFinished: Scalars["Boolean"]; - revision?: Maybe; - scheduledTime?: Maybe; - spawnHostLink?: Maybe; - startTime?: Maybe; - status: Scalars["String"]; + projectId: Scalars["String"]["output"]; + projectIdentifier?: Maybe; + requester: Scalars["String"]["output"]; + resetWhenFinished: Scalars["Boolean"]["output"]; + revision?: Maybe; + scheduledTime?: Maybe; + spawnHostLink?: Maybe; + startTime?: Maybe; + status: Scalars["String"]["output"]; + /** @deprecated Use files instead */ taskFiles: TaskFiles; - taskGroup?: Maybe; - taskGroupMaxHosts?: Maybe; + taskGroup?: Maybe; + taskGroupMaxHosts?: Maybe; /** taskLogs returns the tail 100 lines of the task's logs. */ taskLogs: TaskLogs; tests: TaskTestResult; - timeTaken?: Maybe; - totalTestCount: Scalars["Int"]; + timeTaken?: Maybe; + totalTestCount: Scalars["Int"]["output"]; versionMetadata: Version; }; @@ -2412,46 +2476,46 @@ export type TaskAnnotationSettingsInput = { export type TaskContainerCreationOpts = { __typename?: "TaskContainerCreationOpts"; - arch: Scalars["String"]; - cpu: Scalars["Int"]; - image: Scalars["String"]; - memoryMB: Scalars["Int"]; - os: Scalars["String"]; - workingDir: Scalars["String"]; + arch: Scalars["String"]["output"]; + cpu: Scalars["Int"]["output"]; + image: Scalars["String"]["output"]; + memoryMB: Scalars["Int"]["output"]; + os: Scalars["String"]["output"]; + workingDir: Scalars["String"]["output"]; }; export type TaskEndDetail = { __typename?: "TaskEndDetail"; - description?: Maybe; + description?: Maybe; oomTracker: OomTrackerInfo; - status: Scalars["String"]; - timedOut?: Maybe; - timeoutType?: Maybe; - traceID?: Maybe; - type: Scalars["String"]; + status: Scalars["String"]["output"]; + timedOut?: Maybe; + timeoutType?: Maybe; + traceID?: Maybe; + type: Scalars["String"]["output"]; }; export type TaskEventLogData = { __typename?: "TaskEventLogData"; - hostId?: Maybe; - jiraIssue?: Maybe; - jiraLink?: Maybe; - podId?: Maybe; - priority?: Maybe; - status?: Maybe; - timestamp?: Maybe; - userId?: Maybe; + hostId?: Maybe; + jiraIssue?: Maybe; + jiraLink?: Maybe; + podId?: Maybe; + priority?: Maybe; + status?: Maybe; + timestamp?: Maybe; + userId?: Maybe; }; export type TaskEventLogEntry = { __typename?: "TaskEventLogEntry"; data: TaskEventLogData; - eventType?: Maybe; - id: Scalars["String"]; - processedAt: Scalars["Time"]; - resourceId: Scalars["String"]; - resourceType: Scalars["String"]; - timestamp?: Maybe; + eventType?: Maybe; + id: Scalars["String"]["output"]; + processedAt: Scalars["Time"]["output"]; + resourceId: Scalars["String"]["output"]; + resourceType: Scalars["String"]["output"]; + timestamp?: Maybe; }; /** @@ -2460,37 +2524,37 @@ export type TaskEventLogEntry = { */ export type TaskFiles = { __typename?: "TaskFiles"; - fileCount: Scalars["Int"]; + fileCount: Scalars["Int"]["output"]; groupedFiles: Array; }; /** TaskFilterOptions defines the parameters that are used when fetching tasks from a Version. */ export type TaskFilterOptions = { - baseStatuses?: InputMaybe>; + baseStatuses?: InputMaybe>; /** @deprecated Use includeNeverActivatedTasks instead */ - includeEmptyActivation?: InputMaybe; - includeNeverActivatedTasks?: InputMaybe; - limit?: InputMaybe; - page?: InputMaybe; + includeEmptyActivation?: InputMaybe; + includeNeverActivatedTasks?: InputMaybe; + limit?: InputMaybe; + page?: InputMaybe; sorts?: InputMaybe>; - statuses?: InputMaybe>; - taskName?: InputMaybe; - variant?: InputMaybe; + statuses?: InputMaybe>; + taskName?: InputMaybe; + variant?: InputMaybe; }; export type TaskInfo = { __typename?: "TaskInfo"; - id?: Maybe; - name?: Maybe; + id?: Maybe; + name?: Maybe; }; export type TaskLogLinks = { __typename?: "TaskLogLinks"; - agentLogLink?: Maybe; - allLogLink?: Maybe; - eventLogLink?: Maybe; - systemLogLink?: Maybe; - taskLogLink?: Maybe; + agentLogLink?: Maybe; + allLogLink?: Maybe; + eventLogLink?: Maybe; + systemLogLink?: Maybe; + taskLogLink?: Maybe; }; /** @@ -2501,11 +2565,11 @@ export type TaskLogs = { __typename?: "TaskLogs"; agentLogs: Array; allLogs: Array; - defaultLogger: Scalars["String"]; + defaultLogger: Scalars["String"]["output"]; eventLogs: Array; - execution: Scalars["Int"]; + execution: Scalars["Int"]["output"]; systemLogs: Array; - taskId: Scalars["String"]; + taskId: Scalars["String"]["output"]; taskLogs: Array; }; @@ -2515,9 +2579,9 @@ export type TaskLogs = { */ export type TaskQueueDistro = { __typename?: "TaskQueueDistro"; - hostCount: Scalars["Int"]; - id: Scalars["ID"]; - taskCount: Scalars["Int"]; + hostCount: Scalars["Int"]["output"]; + id: Scalars["ID"]["output"]; + taskCount: Scalars["Int"]["output"]; }; /** @@ -2527,16 +2591,16 @@ export type TaskQueueDistro = { */ export type TaskQueueItem = { __typename?: "TaskQueueItem"; - activatedBy: Scalars["String"]; - buildVariant: Scalars["String"]; - displayName: Scalars["String"]; - expectedDuration: Scalars["Duration"]; - id: Scalars["ID"]; - priority: Scalars["Int"]; - project: Scalars["String"]; + activatedBy: Scalars["String"]["output"]; + buildVariant: Scalars["String"]["output"]; + displayName: Scalars["String"]["output"]; + expectedDuration: Scalars["Duration"]["output"]; + id: Scalars["ID"]["output"]; + priority: Scalars["Int"]["output"]; + project: Scalars["String"]["output"]; requester: TaskQueueItemType; - revision: Scalars["String"]; - version: Scalars["String"]; + revision: Scalars["String"]["output"]; + version: Scalars["String"]["output"]; }; export enum TaskQueueItemType { @@ -2554,32 +2618,32 @@ export enum TaskSortCategory { export type TaskSpecifier = { __typename?: "TaskSpecifier"; - patchAlias: Scalars["String"]; - taskRegex: Scalars["String"]; - variantRegex: Scalars["String"]; + patchAlias: Scalars["String"]["output"]; + taskRegex: Scalars["String"]["output"]; + variantRegex: Scalars["String"]["output"]; }; export type TaskSpecifierInput = { - patchAlias: Scalars["String"]; - taskRegex: Scalars["String"]; - variantRegex: Scalars["String"]; + patchAlias: Scalars["String"]["input"]; + taskRegex: Scalars["String"]["input"]; + variantRegex: Scalars["String"]["input"]; }; export type TaskStats = { __typename?: "TaskStats"; counts?: Maybe>; - eta?: Maybe; + eta?: Maybe; }; export type TaskSyncOptions = { __typename?: "TaskSyncOptions"; - configEnabled?: Maybe; - patchEnabled?: Maybe; + configEnabled?: Maybe; + patchEnabled?: Maybe; }; export type TaskSyncOptionsInput = { - configEnabled?: InputMaybe; - patchEnabled?: InputMaybe; + configEnabled?: InputMaybe; + patchEnabled?: InputMaybe; }; /** @@ -2589,9 +2653,9 @@ export type TaskSyncOptionsInput = { */ export type TaskTestResult = { __typename?: "TaskTestResult"; - filteredTestCount: Scalars["Int"]; + filteredTestCount: Scalars["Int"]["output"]; testResults: Array; - totalTestCount: Scalars["Int"]; + totalTestCount: Scalars["Int"]["output"]; }; /** @@ -2600,10 +2664,10 @@ export type TaskTestResult = { */ export type TaskTestResultSample = { __typename?: "TaskTestResultSample"; - execution: Scalars["Int"]; - matchingFailedTestNames: Array; - taskId: Scalars["String"]; - totalTestCount: Scalars["Int"]; + execution: Scalars["Int"]["output"]; + matchingFailedTestNames: Array; + taskId: Scalars["String"]["output"]; + totalTestCount: Scalars["Int"]["output"]; }; /** @@ -2611,8 +2675,8 @@ export type TaskTestResultSample = { * It's used to filter for tests with testName and status testStatus. */ export type TestFilter = { - testName: Scalars["String"]; - testStatus: Scalars["String"]; + testName: Scalars["String"]["input"]; + testStatus: Scalars["String"]["input"]; }; /** @@ -2620,39 +2684,39 @@ export type TestFilter = { * It's used to filter, sort, and paginate test results of a task. */ export type TestFilterOptions = { - excludeDisplayNames?: InputMaybe; - groupID?: InputMaybe; - limit?: InputMaybe; - page?: InputMaybe; + excludeDisplayNames?: InputMaybe; + groupID?: InputMaybe; + limit?: InputMaybe; + page?: InputMaybe; sort?: InputMaybe>; - statuses?: InputMaybe>; - testName?: InputMaybe; + statuses?: InputMaybe>; + testName?: InputMaybe; }; export type TestLog = { __typename?: "TestLog"; - lineNum?: Maybe; - url?: Maybe; + lineNum?: Maybe; + url?: Maybe; /** @deprecated Use urlParsley instead */ - urlLobster?: Maybe; - urlParsley?: Maybe; - urlRaw?: Maybe; + urlLobster?: Maybe; + urlParsley?: Maybe; + urlRaw?: Maybe; }; export type TestResult = { __typename?: "TestResult"; - baseStatus?: Maybe; - duration?: Maybe; - endTime?: Maybe; - execution?: Maybe; - exitCode?: Maybe; - groupID?: Maybe; - id: Scalars["String"]; + baseStatus?: Maybe; + duration?: Maybe; + endTime?: Maybe; + execution?: Maybe; + exitCode?: Maybe; + groupID?: Maybe; + id: Scalars["String"]["output"]; logs: TestLog; - startTime?: Maybe; - status: Scalars["String"]; - taskId?: Maybe; - testFile: Scalars["String"]; + startTime?: Maybe; + status: Scalars["String"]["output"]; + taskId?: Maybe; + testFile: Scalars["String"]["output"]; }; export enum TestSortCategory { @@ -2674,42 +2738,44 @@ export type TestSortOptions = { export type TicketFields = { __typename?: "TicketFields"; - assignedTeam?: Maybe; - assigneeDisplayName?: Maybe; - created: Scalars["String"]; - resolutionName?: Maybe; + assignedTeam?: Maybe; + assigneeDisplayName?: Maybe; + created: Scalars["String"]["output"]; + resolutionName?: Maybe; status: JiraStatus; - summary: Scalars["String"]; - updated: Scalars["String"]; + summary: Scalars["String"]["output"]; + updated: Scalars["String"]["output"]; }; export type TriggerAlias = { __typename?: "TriggerAlias"; - alias: Scalars["String"]; - buildVariantRegex: Scalars["String"]; - configFile: Scalars["String"]; - dateCutoff?: Maybe; - level: Scalars["String"]; - project: Scalars["String"]; - status: Scalars["String"]; - taskRegex: Scalars["String"]; + alias: Scalars["String"]["output"]; + buildVariantRegex: Scalars["String"]["output"]; + configFile: Scalars["String"]["output"]; + dateCutoff?: Maybe; + level: Scalars["String"]["output"]; + project: Scalars["String"]["output"]; + status: Scalars["String"]["output"]; + taskRegex: Scalars["String"]["output"]; + unscheduleDownstreamVersions?: Maybe; }; export type TriggerAliasInput = { - alias: Scalars["String"]; - buildVariantRegex: Scalars["String"]; - configFile: Scalars["String"]; - dateCutoff?: InputMaybe; - level: Scalars["String"]; - project: Scalars["String"]; - status: Scalars["String"]; - taskRegex: Scalars["String"]; + alias: Scalars["String"]["input"]; + buildVariantRegex: Scalars["String"]["input"]; + configFile: Scalars["String"]["input"]; + dateCutoff?: InputMaybe; + level: Scalars["String"]["input"]; + project: Scalars["String"]["input"]; + status: Scalars["String"]["input"]; + taskRegex: Scalars["String"]["input"]; + unscheduleDownstreamVersions?: InputMaybe; }; export type UiConfig = { __typename?: "UIConfig"; - defaultProject: Scalars["String"]; - userVoice?: Maybe; + defaultProject: Scalars["String"]["output"]; + userVoice?: Maybe; }; /** @@ -2717,36 +2783,36 @@ export type UiConfig = { * Its fields determine how a given volume will be modified. */ export type UpdateVolumeInput = { - expiration?: InputMaybe; - name?: InputMaybe; - noExpiration?: InputMaybe; - volumeId: Scalars["String"]; + expiration?: InputMaybe; + name?: InputMaybe; + noExpiration?: InputMaybe; + volumeId: Scalars["String"]["input"]; }; export type UpstreamProject = { __typename?: "UpstreamProject"; - owner: Scalars["String"]; - project: Scalars["String"]; - repo: Scalars["String"]; - resourceID: Scalars["String"]; - revision: Scalars["String"]; + owner: Scalars["String"]["output"]; + project: Scalars["String"]["output"]; + repo: Scalars["String"]["output"]; + resourceID: Scalars["String"]["output"]; + revision: Scalars["String"]["output"]; task?: Maybe; - triggerID: Scalars["String"]; - triggerType: Scalars["String"]; + triggerID: Scalars["String"]["output"]; + triggerType: Scalars["String"]["output"]; version?: Maybe; }; export type UseSpruceOptions = { __typename?: "UseSpruceOptions"; - hasUsedMainlineCommitsBefore?: Maybe; - hasUsedSpruceBefore?: Maybe; - spruceV1?: Maybe; + hasUsedMainlineCommitsBefore?: Maybe; + hasUsedSpruceBefore?: Maybe; + spruceV1?: Maybe; }; export type UseSpruceOptionsInput = { - hasUsedMainlineCommitsBefore?: InputMaybe; - hasUsedSpruceBefore?: InputMaybe; - spruceV1?: InputMaybe; + hasUsedMainlineCommitsBefore?: InputMaybe; + hasUsedSpruceBefore?: InputMaybe; + spruceV1?: InputMaybe; }; /** @@ -2755,12 +2821,12 @@ export type UseSpruceOptionsInput = { */ export type User = { __typename?: "User"; - displayName: Scalars["String"]; - emailAddress: Scalars["String"]; + displayName: Scalars["String"]["output"]; + emailAddress: Scalars["String"]["output"]; patches: Patches; permissions: Permissions; subscriptions?: Maybe>; - userId: Scalars["String"]; + userId: Scalars["String"]["output"]; }; /** @@ -2778,10 +2844,10 @@ export type UserPatchesArgs = { */ export type UserConfig = { __typename?: "UserConfig"; - api_key: Scalars["String"]; - api_server_host: Scalars["String"]; - ui_server_host: Scalars["String"]; - user: Scalars["String"]; + api_key: Scalars["String"]["output"]; + api_server_host: Scalars["String"]["output"]; + ui_server_host: Scalars["String"]["output"]; + user: Scalars["String"]["output"]; }; /** @@ -2790,13 +2856,13 @@ export type UserConfig = { */ export type UserSettings = { __typename?: "UserSettings"; - dateFormat?: Maybe; + dateFormat?: Maybe; githubUser?: Maybe; notifications?: Maybe; - region?: Maybe; - slackMemberId?: Maybe; - slackUsername?: Maybe; - timezone?: Maybe; + region?: Maybe; + slackMemberId?: Maybe; + slackUsername?: Maybe; + timezone?: Maybe; useSpruceOptions?: Maybe; }; @@ -2805,67 +2871,67 @@ export type UserSettings = { * It is used to update user information such as GitHub or Slack username. */ export type UserSettingsInput = { - dateFormat?: InputMaybe; + dateFormat?: InputMaybe; githubUser?: InputMaybe; notifications?: InputMaybe; - region?: InputMaybe; - slackMemberId?: InputMaybe; - slackUsername?: InputMaybe; - timezone?: InputMaybe; + region?: InputMaybe; + slackMemberId?: InputMaybe; + slackUsername?: InputMaybe; + timezone?: InputMaybe; useSpruceOptions?: InputMaybe; }; export type VariantTask = { __typename?: "VariantTask"; - name: Scalars["String"]; - tasks: Array; + name: Scalars["String"]["output"]; + tasks: Array; }; export type VariantTasks = { displayTasks: Array; - tasks: Array; - variant: Scalars["String"]; + tasks: Array; + variant: Scalars["String"]["input"]; }; /** Version models a commit within a project. */ export type Version = { __typename?: "Version"; - activated?: Maybe; - author: Scalars["String"]; - baseTaskStatuses: Array; + activated?: Maybe; + author: Scalars["String"]["output"]; + baseTaskStatuses: Array; baseVersion?: Maybe; - branch: Scalars["String"]; + branch: Scalars["String"]["output"]; buildVariantStats?: Maybe>; buildVariants?: Maybe>>; childVersions?: Maybe>>; - createTime: Scalars["Time"]; - errors: Array; + createTime: Scalars["Time"]["output"]; + errors: Array; externalLinksForMetadata: Array; - finishTime?: Maybe; + finishTime?: Maybe; gitTags?: Maybe>; - id: Scalars["String"]; - isPatch: Scalars["Boolean"]; + id: Scalars["String"]["output"]; + isPatch: Scalars["Boolean"]["output"]; manifest?: Maybe; - message: Scalars["String"]; - order: Scalars["Int"]; + message: Scalars["String"]["output"]; + order: Scalars["Int"]["output"]; parameters: Array; patch?: Maybe; previousVersion?: Maybe; - project: Scalars["String"]; - projectIdentifier: Scalars["String"]; + project: Scalars["String"]["output"]; + projectIdentifier: Scalars["String"]["output"]; projectMetadata?: Maybe; - repo: Scalars["String"]; - requester: Scalars["String"]; - revision: Scalars["String"]; - startTime?: Maybe; - status: Scalars["String"]; - taskCount?: Maybe; + repo: Scalars["String"]["output"]; + requester: Scalars["String"]["output"]; + revision: Scalars["String"]["output"]; + startTime?: Maybe; + status: Scalars["String"]["output"]; + taskCount?: Maybe; taskStatusStats?: Maybe; - taskStatuses: Array; + taskStatuses: Array; tasks: VersionTasks; upstreamProject?: Maybe; versionTiming?: Maybe; - warnings: Array; + warnings: Array; }; /** Version models a commit within a project. */ @@ -2890,14 +2956,14 @@ export type VersionTasksArgs = { export type VersionTasks = { __typename?: "VersionTasks"; - count: Scalars["Int"]; + count: Scalars["Int"]["output"]; data: Array; }; export type VersionTiming = { __typename?: "VersionTiming"; - makespan?: Maybe; - timeTaken?: Maybe; + makespan?: Maybe; + timeTaken?: Maybe; }; /** @@ -2905,26 +2971,26 @@ export type VersionTiming = { * It contains an array of taskIds to restart for a given versionId. */ export type VersionToRestart = { - taskIds: Array; - versionId: Scalars["String"]; + taskIds: Array; + versionId: Scalars["String"]["input"]; }; export type Volume = { __typename?: "Volume"; - availabilityZone: Scalars["String"]; - createdBy: Scalars["String"]; - creationTime?: Maybe; - deviceName?: Maybe; - displayName: Scalars["String"]; - expiration?: Maybe; - homeVolume: Scalars["Boolean"]; + availabilityZone: Scalars["String"]["output"]; + createdBy: Scalars["String"]["output"]; + creationTime?: Maybe; + deviceName?: Maybe; + displayName: Scalars["String"]["output"]; + expiration?: Maybe; + homeVolume: Scalars["Boolean"]["output"]; host?: Maybe; - hostID: Scalars["String"]; - id: Scalars["String"]; - migrating: Scalars["Boolean"]; - noExpiration: Scalars["Boolean"]; - size: Scalars["Int"]; - type: Scalars["String"]; + hostID: Scalars["String"]["output"]; + id: Scalars["String"]["output"]; + migrating: Scalars["Boolean"]["output"]; + noExpiration: Scalars["Boolean"]["output"]; + size: Scalars["Int"]["output"]; + type: Scalars["String"]["output"]; }; /** @@ -2932,71 +2998,71 @@ export type Volume = { * Its fields are used to attach the volume with volumeId to the host with hostId. */ export type VolumeHost = { - hostId: Scalars["String"]; - volumeId: Scalars["String"]; + hostId: Scalars["String"]["input"]; + volumeId: Scalars["String"]["input"]; }; export type Webhook = { __typename?: "Webhook"; - endpoint: Scalars["String"]; - secret: Scalars["String"]; + endpoint: Scalars["String"]["output"]; + secret: Scalars["String"]["output"]; }; export type WebhookHeader = { __typename?: "WebhookHeader"; - key: Scalars["String"]; - value: Scalars["String"]; + key: Scalars["String"]["output"]; + value: Scalars["String"]["output"]; }; export type WebhookHeaderInput = { - key: Scalars["String"]; - value: Scalars["String"]; + key: Scalars["String"]["input"]; + value: Scalars["String"]["input"]; }; export type WebhookInput = { - endpoint: Scalars["String"]; - secret: Scalars["String"]; + endpoint: Scalars["String"]["input"]; + secret: Scalars["String"]["input"]; }; export type WebhookSubscriber = { __typename?: "WebhookSubscriber"; headers: Array>; - minDelayMs: Scalars["Int"]; - retries: Scalars["Int"]; - secret: Scalars["String"]; - timeoutMs: Scalars["Int"]; - url: Scalars["String"]; + minDelayMs: Scalars["Int"]["output"]; + retries: Scalars["Int"]["output"]; + secret: Scalars["String"]["output"]; + timeoutMs: Scalars["Int"]["output"]; + url: Scalars["String"]["output"]; }; export type WebhookSubscriberInput = { headers: Array>; - minDelayMs?: InputMaybe; - retries?: InputMaybe; - secret: Scalars["String"]; - timeoutMs?: InputMaybe; - url: Scalars["String"]; + minDelayMs?: InputMaybe; + retries?: InputMaybe; + secret: Scalars["String"]["input"]; + timeoutMs?: InputMaybe; + url: Scalars["String"]["input"]; }; export type WorkstationConfig = { __typename?: "WorkstationConfig"; - gitClone?: Maybe; + gitClone?: Maybe; setupCommands?: Maybe>; }; export type WorkstationConfigInput = { - gitClone?: InputMaybe; + gitClone?: InputMaybe; setupCommands?: InputMaybe>; }; export type WorkstationSetupCommand = { __typename?: "WorkstationSetupCommand"; - command: Scalars["String"]; - directory: Scalars["String"]; + command: Scalars["String"]["output"]; + directory: Scalars["String"]["output"]; }; export type WorkstationSetupCommandInput = { - command: Scalars["String"]; - directory?: InputMaybe; + command: Scalars["String"]["input"]; + directory?: InputMaybe; }; export type AnnotationFragment = { @@ -4326,7 +4392,7 @@ export type UpstreamProjectFragment = { }; export type AbortTaskMutationVariables = Exact<{ - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }>; export type AbortTaskMutation = { @@ -4345,10 +4411,10 @@ export type AbortTaskMutation = { }; export type AddAnnotationIssueMutationVariables = Exact<{ - taskId: Scalars["String"]; - execution: Scalars["Int"]; + taskId: Scalars["String"]["input"]; + execution: Scalars["Int"]["input"]; apiIssue: IssueLinkInput; - isIssue: Scalars["Boolean"]; + isIssue: Scalars["Boolean"]["input"]; }>; export type AddAnnotationIssueMutation = { @@ -4357,7 +4423,7 @@ export type AddAnnotationIssueMutation = { }; export type AddFavoriteProjectMutationVariables = Exact<{ - identifier: Scalars["String"]; + identifier: Scalars["String"]["input"]; }>; export type AddFavoriteProjectMutation = { @@ -4387,7 +4453,7 @@ export type AttachProjectToNewRepoMutation = { }; export type AttachProjectToRepoMutationVariables = Exact<{ - projectId: Scalars["String"]; + projectId: Scalars["String"]["input"]; }>; export type AttachProjectToRepoMutation = { @@ -4424,7 +4490,7 @@ export type CopyDistroMutation = { export type CopyProjectMutationVariables = Exact<{ project: CopyProjectInput; - requestS3Creds: Scalars["Boolean"]; + requestS3Creds: Scalars["Boolean"]["input"]; }>; export type CopyProjectMutation = { @@ -4443,7 +4509,7 @@ export type CreateDistroMutation = { export type CreateProjectMutationVariables = Exact<{ project: CreateProjectInput; - requestS3Creds: Scalars["Boolean"]; + requestS3Creds: Scalars["Boolean"]["input"]; }>; export type CreateProjectMutation = { @@ -4465,9 +4531,9 @@ export type CreatePublicKeyMutation = { }; export type DeactivateStepbackTaskMutationVariables = Exact<{ - projectId: Scalars["String"]; - buildVariantName: Scalars["String"]; - taskName: Scalars["String"]; + projectId: Scalars["String"]["input"]; + buildVariantName: Scalars["String"]["input"]; + taskName: Scalars["String"]["input"]; }>; export type DeactivateStepbackTaskMutation = { @@ -4476,7 +4542,7 @@ export type DeactivateStepbackTaskMutation = { }; export type DefaultSectionToRepoMutationVariables = Exact<{ - projectId: Scalars["String"]; + projectId: Scalars["String"]["input"]; section: ProjectSettingsSection; }>; @@ -4486,7 +4552,7 @@ export type DefaultSectionToRepoMutation = { }; export type DeleteDistroMutationVariables = Exact<{ - distroId: Scalars["String"]; + distroId: Scalars["String"]["input"]; }>; export type DeleteDistroMutation = { @@ -4495,7 +4561,7 @@ export type DeleteDistroMutation = { }; export type DeleteProjectMutationVariables = Exact<{ - projectId: Scalars["String"]; + projectId: Scalars["String"]["input"]; }>; export type DeleteProjectMutation = { @@ -4504,7 +4570,7 @@ export type DeleteProjectMutation = { }; export type DeleteSubscriptionsMutationVariables = Exact<{ - subscriptionIds: Array; + subscriptionIds: Array; }>; export type DeleteSubscriptionsMutation = { @@ -4513,7 +4579,7 @@ export type DeleteSubscriptionsMutation = { }; export type DetachProjectFromRepoMutationVariables = Exact<{ - projectId: Scalars["String"]; + projectId: Scalars["String"]["input"]; }>; export type DetachProjectFromRepoMutation = { @@ -4522,7 +4588,7 @@ export type DetachProjectFromRepoMutation = { }; export type DetachVolumeFromHostMutationVariables = Exact<{ - volumeId: Scalars["String"]; + volumeId: Scalars["String"]["input"]; }>; export type DetachVolumeFromHostMutation = { @@ -4531,10 +4597,10 @@ export type DetachVolumeFromHostMutation = { }; export type EditAnnotationNoteMutationVariables = Exact<{ - taskId: Scalars["String"]; - execution: Scalars["Int"]; - originalMessage: Scalars["String"]; - newMessage: Scalars["String"]; + taskId: Scalars["String"]["input"]; + execution: Scalars["Int"]["input"]; + originalMessage: Scalars["String"]["input"]; + newMessage: Scalars["String"]["input"]; }>; export type EditAnnotationNoteMutation = { @@ -4543,17 +4609,17 @@ export type EditAnnotationNoteMutation = { }; export type EditSpawnHostMutationVariables = Exact<{ - hostId: Scalars["String"]; - displayName?: InputMaybe; + hostId: Scalars["String"]["input"]; + displayName?: InputMaybe; addedInstanceTags?: InputMaybe>; deletedInstanceTags?: InputMaybe>; - volumeId?: InputMaybe; - instanceType?: InputMaybe; - expiration?: InputMaybe; - noExpiration?: InputMaybe; - servicePassword?: InputMaybe; + volumeId?: InputMaybe; + instanceType?: InputMaybe; + expiration?: InputMaybe; + noExpiration?: InputMaybe; + servicePassword?: InputMaybe; publicKey?: InputMaybe; - savePublicKey?: InputMaybe; + savePublicKey?: InputMaybe; }>; export type EditSpawnHostMutation = { @@ -4603,8 +4669,8 @@ export type EditSpawnHostMutation = { }; export type EnqueuePatchMutationVariables = Exact<{ - patchId: Scalars["String"]; - commitMessage?: InputMaybe; + patchId: Scalars["String"]["input"]; + commitMessage?: InputMaybe; }>; export type EnqueuePatchMutation = { @@ -4613,8 +4679,8 @@ export type EnqueuePatchMutation = { }; export type BuildBaronCreateTicketMutationVariables = Exact<{ - taskId: Scalars["String"]; - execution?: InputMaybe; + taskId: Scalars["String"]["input"]; + execution?: InputMaybe; }>; export type BuildBaronCreateTicketMutation = { @@ -4623,7 +4689,7 @@ export type BuildBaronCreateTicketMutation = { }; export type ForceRepotrackerRunMutationVariables = Exact<{ - projectId: Scalars["String"]; + projectId: Scalars["String"]["input"]; }>; export type ForceRepotrackerRunMutation = { @@ -4632,7 +4698,7 @@ export type ForceRepotrackerRunMutation = { }; export type MigrateVolumeMutationVariables = Exact<{ - volumeId: Scalars["String"]; + volumeId: Scalars["String"]["input"]; spawnHostInput: SpawnHostInput; }>; @@ -4642,10 +4708,10 @@ export type MigrateVolumeMutation = { }; export type MoveAnnotationIssueMutationVariables = Exact<{ - taskId: Scalars["String"]; - execution: Scalars["Int"]; + taskId: Scalars["String"]["input"]; + execution: Scalars["Int"]["input"]; apiIssue: IssueLinkInput; - isIssue: Scalars["Boolean"]; + isIssue: Scalars["Boolean"]["input"]; }>; export type MoveAnnotationIssueMutation = { @@ -4654,7 +4720,7 @@ export type MoveAnnotationIssueMutation = { }; export type OverrideTaskDependenciesMutationVariables = Exact<{ - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }>; export type OverrideTaskDependenciesMutation = { @@ -4668,8 +4734,8 @@ export type OverrideTaskDependenciesMutation = { }; export type PromoteVarsToRepoMutationVariables = Exact<{ - projectId: Scalars["String"]; - varNames: Array; + projectId: Scalars["String"]["input"]; + varNames: Array; }>; export type PromoteVarsToRepoMutation = { @@ -4678,10 +4744,10 @@ export type PromoteVarsToRepoMutation = { }; export type RemoveAnnotationIssueMutationVariables = Exact<{ - taskId: Scalars["String"]; - execution: Scalars["Int"]; + taskId: Scalars["String"]["input"]; + execution: Scalars["Int"]["input"]; apiIssue: IssueLinkInput; - isIssue: Scalars["Boolean"]; + isIssue: Scalars["Boolean"]["input"]; }>; export type RemoveAnnotationIssueMutation = { @@ -4690,7 +4756,7 @@ export type RemoveAnnotationIssueMutation = { }; export type RemoveFavoriteProjectMutationVariables = Exact<{ - identifier: Scalars["String"]; + identifier: Scalars["String"]["input"]; }>; export type RemoveFavoriteProjectMutation = { @@ -4707,8 +4773,8 @@ export type RemoveFavoriteProjectMutation = { }; export type RemoveItemFromCommitQueueMutationVariables = Exact<{ - commitQueueId: Scalars["String"]; - issue: Scalars["String"]; + commitQueueId: Scalars["String"]["input"]; + issue: Scalars["String"]["input"]; }>; export type RemoveItemFromCommitQueueMutation = { @@ -4717,7 +4783,7 @@ export type RemoveItemFromCommitQueueMutation = { }; export type RemovePublicKeyMutationVariables = Exact<{ - keyName: Scalars["String"]; + keyName: Scalars["String"]["input"]; }>; export type RemovePublicKeyMutation = { @@ -4730,7 +4796,7 @@ export type RemovePublicKeyMutation = { }; export type RemoveVolumeMutationVariables = Exact<{ - volumeId: Scalars["String"]; + volumeId: Scalars["String"]["input"]; }>; export type RemoveVolumeMutation = { @@ -4739,7 +4805,7 @@ export type RemoveVolumeMutation = { }; export type ReprovisionToNewMutationVariables = Exact<{ - hostIds: Array; + hostIds: Array; }>; export type ReprovisionToNewMutation = { @@ -4748,7 +4814,7 @@ export type ReprovisionToNewMutation = { }; export type RestartJasperMutationVariables = Exact<{ - hostIds: Array; + hostIds: Array; }>; export type RestartJasperMutation = { @@ -4757,8 +4823,8 @@ export type RestartJasperMutation = { }; export type RestartTaskMutationVariables = Exact<{ - taskId: Scalars["String"]; - failedOnly: Scalars["Boolean"]; + taskId: Scalars["String"]["input"]; + failedOnly: Scalars["Boolean"]["input"]; }>; export type RestartTaskMutation = { @@ -4777,8 +4843,8 @@ export type RestartTaskMutation = { }; export type RestartVersionsMutationVariables = Exact<{ - versionId: Scalars["String"]; - abort: Scalars["Boolean"]; + versionId: Scalars["String"]["input"]; + abort: Scalars["Boolean"]["input"]; versionsToRestart: Array; }>; @@ -4856,7 +4922,7 @@ export type SaveSubscriptionForUserMutation = { }; export type SchedulePatchMutationVariables = Exact<{ - patchId: Scalars["String"]; + patchId: Scalars["String"]["input"]; configure: PatchConfigure; }>; @@ -4884,7 +4950,7 @@ export type SchedulePatchMutation = { }; export type ScheduleTasksMutationVariables = Exact<{ - taskIds: Array; + taskIds: Array; }>; export type ScheduleTasksMutation = { @@ -4902,7 +4968,7 @@ export type ScheduleTasksMutation = { }; export type ScheduleUndispatchedBaseTasksMutationVariables = Exact<{ - patchId: Scalars["String"]; + patchId: Scalars["String"]["input"]; }>; export type ScheduleUndispatchedBaseTasksMutation = { @@ -4916,8 +4982,8 @@ export type ScheduleUndispatchedBaseTasksMutation = { }; export type SetPatchPriorityMutationVariables = Exact<{ - patchId: Scalars["String"]; - priority: Scalars["Int"]; + patchId: Scalars["String"]["input"]; + priority: Scalars["Int"]["input"]; }>; export type SetPatchPriorityMutation = { @@ -4926,8 +4992,8 @@ export type SetPatchPriorityMutation = { }; export type SetPatchVisibilityMutationVariables = Exact<{ - patchIds: Array; - hidden: Scalars["Boolean"]; + patchIds: Array; + hidden: Scalars["Boolean"]["input"]; }>; export type SetPatchVisibilityMutation = { @@ -4936,8 +5002,8 @@ export type SetPatchVisibilityMutation = { }; export type SetTaskPriorityMutationVariables = Exact<{ - taskId: Scalars["String"]; - priority: Scalars["Int"]; + taskId: Scalars["String"]["input"]; + priority: Scalars["Int"]["input"]; }>; export type SetTaskPriorityMutation = { @@ -4969,8 +5035,8 @@ export type SpawnVolumeMutation = { }; export type UnschedulePatchTasksMutationVariables = Exact<{ - patchId: Scalars["String"]; - abort: Scalars["Boolean"]; + patchId: Scalars["String"]["input"]; + abort: Scalars["Boolean"]["input"]; }>; export type UnschedulePatchTasksMutation = { @@ -4979,7 +5045,7 @@ export type UnschedulePatchTasksMutation = { }; export type UnscheduleTaskMutationVariables = Exact<{ - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }>; export type UnscheduleTaskMutation = { @@ -4988,9 +5054,9 @@ export type UnscheduleTaskMutation = { }; export type UpdateHostStatusMutationVariables = Exact<{ - hostIds: Array; - status: Scalars["String"]; - notes?: InputMaybe; + hostIds: Array; + status: Scalars["String"]["input"]; + notes?: InputMaybe; }>; export type UpdateHostStatusMutation = { @@ -4999,8 +5065,8 @@ export type UpdateHostStatusMutation = { }; export type UpdatePatchDescriptionMutationVariables = Exact<{ - patchId: Scalars["String"]; - description: Scalars["String"]; + patchId: Scalars["String"]["input"]; + description: Scalars["String"]["input"]; }>; export type UpdatePatchDescriptionMutation = { @@ -5024,7 +5090,7 @@ export type UpdatePatchDescriptionMutation = { }; export type UpdatePublicKeyMutationVariables = Exact<{ - targetKeyName: Scalars["String"]; + targetKeyName: Scalars["String"]["input"]; updateInfo: PublicKeyInput; }>; @@ -5038,7 +5104,7 @@ export type UpdatePublicKeyMutation = { }; export type UpdateSpawnHostStatusMutationVariables = Exact<{ - hostId: Scalars["String"]; + hostId: Scalars["String"]["input"]; action: SpawnHostStatusActions; }>; @@ -5072,8 +5138,30 @@ export type AwsRegionsQuery = { awsRegions?: Array | null; }; +export type DistroEventsQueryVariables = Exact<{ + distroId: Scalars["String"]["input"]; + limit?: InputMaybe; + before?: InputMaybe; +}>; + +export type DistroEventsQuery = { + __typename?: "Query"; + distroEvents: { + __typename?: "DistroEventsPayload"; + count: number; + eventLogEntries: Array<{ + __typename?: "DistroEvent"; + after?: any | null; + before?: any | null; + data?: any | null; + timestamp: Date; + user: string; + }>; + }; +}; + export type DistroTaskQueueQueryVariables = Exact<{ - distroId: Scalars["String"]; + distroId: Scalars["String"]["input"]; }>; export type DistroTaskQueueQuery = { @@ -5093,7 +5181,7 @@ export type DistroTaskQueueQuery = { }; export type DistroQueryVariables = Exact<{ - distroId: Scalars["String"]; + distroId: Scalars["String"]["input"]; }>; export type DistroQuery = { @@ -5101,7 +5189,7 @@ export type DistroQuery = { distro?: { __typename?: "Distro"; aliases: Array; - arch: string; + arch: Arch; authorizedKeysFile: string; cloneMethod: CloneMethod; containerPool: string; @@ -5111,7 +5199,7 @@ export type DistroQuery = { isVirtualWorkStation: boolean; name: string; note: string; - provider: string; + provider: Provider; providerSettingsList: Array; setup: string; setupAsSudo: boolean; @@ -5124,10 +5212,10 @@ export type DistroQuery = { bootstrapSettings: { __typename?: "BootstrapSettings"; clientDir: string; - communication: string; + communication: CommunicationMethod; jasperBinaryDir: string; jasperCredentialsPath: string; - method: string; + method: BootstrapMethod; rootDir: string; serviceUser: string; shellPath: string; @@ -5159,13 +5247,13 @@ export type DistroQuery = { hostAllocatorSettings: { __typename?: "HostAllocatorSettings"; acceptableHostIdleTime: number; - feedbackRule: string; + feedbackRule: FeedbackRule; futureHostFraction: number; - hostsOverallocatedRule: string; + hostsOverallocatedRule: OverallocatedRule; maximumHosts: number; minimumHosts: number; - roundingRule: string; - version: string; + roundingRule: RoundingRule; + version: HostAllocatorVersion; }; iceCreamSettings: { __typename?: "IceCreamSettings"; @@ -5188,7 +5276,7 @@ export type DistroQuery = { }; export type FailedTaskStatusIconTooltipQueryVariables = Exact<{ - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }>; export type FailedTaskStatusIconTooltipQuery = { @@ -5210,8 +5298,8 @@ export type FailedTaskStatusIconTooltipQuery = { }; export type AgentLogsQueryVariables = Exact<{ - id: Scalars["String"]; - execution?: InputMaybe; + id: Scalars["String"]["input"]; + execution?: InputMaybe; }>; export type AgentLogsQuery = { @@ -5233,8 +5321,8 @@ export type AgentLogsQuery = { }; export type AllLogsQueryVariables = Exact<{ - id: Scalars["String"]; - execution?: InputMaybe; + id: Scalars["String"]["input"]; + execution?: InputMaybe; }>; export type AllLogsQuery = { @@ -5256,8 +5344,8 @@ export type AllLogsQuery = { }; export type AnnotationEventDataQueryVariables = Exact<{ - taskId: Scalars["String"]; - execution?: InputMaybe; + taskId: Scalars["String"]["input"]; + execution?: InputMaybe; }>; export type AnnotationEventDataQuery = { @@ -5325,7 +5413,7 @@ export type AnnotationEventDataQuery = { }; export type BaseVersionAndTaskQueryVariables = Exact<{ - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }>; export type BaseVersionAndTaskQuery = { @@ -5357,8 +5445,8 @@ export type BaseVersionAndTaskQuery = { }; export type BuildBaronConfiguredQueryVariables = Exact<{ - taskId: Scalars["String"]; - execution: Scalars["Int"]; + taskId: Scalars["String"]["input"]; + execution: Scalars["Int"]["input"]; }>; export type BuildBaronConfiguredQuery = { @@ -5367,8 +5455,8 @@ export type BuildBaronConfiguredQuery = { }; export type BuildBaronQueryVariables = Exact<{ - taskId: Scalars["String"]; - execution: Scalars["Int"]; + taskId: Scalars["String"]["input"]; + execution: Scalars["Int"]["input"]; }>; export type BuildBaronQuery = { @@ -5400,7 +5488,7 @@ export type BuildBaronQuery = { }; export type BuildVariantStatsQueryVariables = Exact<{ - id: Scalars["String"]; + id: Scalars["String"]["input"]; }>; export type BuildVariantStatsQuery = { @@ -5422,8 +5510,8 @@ export type BuildVariantStatsQuery = { }; export type BuildVariantsForTaskNameQueryVariables = Exact<{ - projectIdentifier: Scalars["String"]; - taskName: Scalars["String"]; + projectIdentifier: Scalars["String"]["input"]; + taskName: Scalars["String"]["input"]; }>; export type BuildVariantsForTaskNameQuery = { @@ -5436,7 +5524,7 @@ export type BuildVariantsForTaskNameQuery = { }; export type BuildVariantsWithChildrenQueryVariables = Exact<{ - id: Scalars["String"]; + id: Scalars["String"]["input"]; }>; export type BuildVariantsWithChildrenQuery = { @@ -5497,7 +5585,7 @@ export type ClientConfigQuery = { }; export type CodeChangesQueryVariables = Exact<{ - id: Scalars["String"]; + id: Scalars["String"]["input"]; }>; export type CodeChangesQuery = { @@ -5523,7 +5611,7 @@ export type CodeChangesQuery = { }; export type CommitQueueQueryVariables = Exact<{ - projectIdentifier: Scalars["String"]; + projectIdentifier: Scalars["String"]["input"]; }>; export type CommitQueueQuery = { @@ -5565,7 +5653,7 @@ export type CommitQueueQuery = { }; export type CreatedTicketsQueryVariables = Exact<{ - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }>; export type CreatedTicketsQuery = { @@ -5586,8 +5674,8 @@ export type CreatedTicketsQuery = { }; export type DisplayTaskQueryVariables = Exact<{ - taskId: Scalars["String"]; - execution?: InputMaybe; + taskId: Scalars["String"]["input"]; + execution?: InputMaybe; }>; export type DisplayTaskQuery = { @@ -5603,7 +5691,7 @@ export type DisplayTaskQuery = { }; export type DistrosQueryVariables = Exact<{ - onlySpawnable: Scalars["Boolean"]; + onlySpawnable: Scalars["Boolean"]["input"]; }>; export type DistrosQuery = { @@ -5626,7 +5714,7 @@ export type GithubOrgsQuery = { }; export type GithubProjectConflictsQueryVariables = Exact<{ - projectId: Scalars["String"]; + projectId: Scalars["String"]["input"]; }>; export type GithubProjectConflictsQuery = { @@ -5640,16 +5728,16 @@ export type GithubProjectConflictsQuery = { }; export type HasVersionQueryVariables = Exact<{ - id: Scalars["String"]; + id: Scalars["String"]["input"]; }>; export type HasVersionQuery = { __typename?: "Query"; hasVersion: boolean }; export type HostEventsQueryVariables = Exact<{ - id: Scalars["String"]; - tag: Scalars["String"]; - limit?: InputMaybe; - page?: InputMaybe; + id: Scalars["String"]["input"]; + tag: Scalars["String"]["input"]; + limit?: InputMaybe; + page?: InputMaybe; }>; export type HostEventsQuery = { @@ -5689,7 +5777,7 @@ export type HostEventsQuery = { }; export type HostQueryVariables = Exact<{ - id: Scalars["String"]; + id: Scalars["String"]["input"]; }>; export type HostQuery = { @@ -5728,7 +5816,7 @@ export type InstanceTypesQuery = { }; export type IsPatchConfiguredQueryVariables = Exact<{ - id: Scalars["String"]; + id: Scalars["String"]["input"]; }>; export type IsPatchConfiguredQuery = { @@ -5743,8 +5831,8 @@ export type IsPatchConfiguredQuery = { }; export type CustomCreatedIssuesQueryVariables = Exact<{ - taskId: Scalars["String"]; - execution?: InputMaybe; + taskId: Scalars["String"]["input"]; + execution?: InputMaybe; }>; export type CustomCreatedIssuesQuery = { @@ -5787,8 +5875,8 @@ export type CustomCreatedIssuesQuery = { }; export type IssuesQueryVariables = Exact<{ - taskId: Scalars["String"]; - execution?: InputMaybe; + taskId: Scalars["String"]["input"]; + execution?: InputMaybe; }>; export type IssuesQuery = { @@ -5831,8 +5919,8 @@ export type IssuesQuery = { }; export type SuspectedIssuesQueryVariables = Exact<{ - taskId: Scalars["String"]; - execution?: InputMaybe; + taskId: Scalars["String"]["input"]; + execution?: InputMaybe; }>; export type SuspectedIssuesQuery = { @@ -5875,8 +5963,8 @@ export type SuspectedIssuesQuery = { }; export type LastMainlineCommitQueryVariables = Exact<{ - projectIdentifier: Scalars["String"]; - skipOrderNumber: Scalars["Int"]; + projectIdentifier: Scalars["String"]["input"]; + skipOrderNumber: Scalars["Int"]["input"]; buildVariantOptions: BuildVariantOptions; }>; @@ -5904,7 +5992,7 @@ export type LastMainlineCommitQuery = { }; export type LogkeeperBuildMetadataQueryVariables = Exact<{ - buildId: Scalars["String"]; + buildId: Scalars["String"]["input"]; }>; export type LogkeeperBuildMetadataQuery = { @@ -6167,7 +6255,7 @@ export type MyVolumesQuery = { }; export type OtherUserQueryVariables = Exact<{ - userId?: InputMaybe; + userId?: InputMaybe; }>; export type OtherUserQuery = { @@ -6177,7 +6265,7 @@ export type OtherUserQuery = { }; export type ConfigurePatchQueryVariables = Exact<{ - id: Scalars["String"]; + id: Scalars["String"]["input"]; }>; export type ConfigurePatchQuery = { @@ -6238,7 +6326,7 @@ export type ConfigurePatchQuery = { }; export type PatchTaskStatusesQueryVariables = Exact<{ - id: Scalars["String"]; + id: Scalars["String"]["input"]; }>; export type PatchTaskStatusesQuery = { @@ -6252,7 +6340,7 @@ export type PatchTaskStatusesQuery = { }; export type PatchQueryVariables = Exact<{ - id: Scalars["String"]; + id: Scalars["String"]["input"]; }>; export type PatchQuery = { @@ -6281,9 +6369,9 @@ export type PatchQuery = { }; export type PodEventsQueryVariables = Exact<{ - id: Scalars["String"]; - limit?: InputMaybe; - page?: InputMaybe; + id: Scalars["String"]["input"]; + limit?: InputMaybe; + page?: InputMaybe; }>; export type PodEventsQuery = { @@ -6323,7 +6411,7 @@ export type PodEventsQuery = { }; export type PodQueryVariables = Exact<{ - podId: Scalars["String"]; + podId: Scalars["String"]["input"]; }>; export type PodQuery = { @@ -6352,7 +6440,7 @@ export type PodQuery = { }; export type ProjectBannerQueryVariables = Exact<{ - identifier: Scalars["String"]; + identifier: Scalars["String"]["input"]; }>; export type ProjectBannerQuery = { @@ -6369,9 +6457,9 @@ export type ProjectBannerQuery = { }; export type ProjectEventLogsQueryVariables = Exact<{ - identifier: Scalars["String"]; - limit?: InputMaybe; - before?: InputMaybe; + identifier: Scalars["String"]["input"]; + limit?: InputMaybe; + before?: InputMaybe; }>; export type ProjectEventLogsQuery = { @@ -6808,7 +6896,7 @@ export type ProjectEventLogsQuery = { }; export type ProjectSettingsQueryVariables = Exact<{ - identifier: Scalars["String"]; + identifier: Scalars["String"]["input"]; }>; export type ProjectSettingsQuery = { @@ -7053,9 +7141,9 @@ export type MyPublicKeysQuery = { }; export type RepoEventLogsQueryVariables = Exact<{ - id: Scalars["String"]; - limit?: InputMaybe; - before?: InputMaybe; + id: Scalars["String"]["input"]; + limit?: InputMaybe; + before?: InputMaybe; }>; export type RepoEventLogsQuery = { @@ -7492,7 +7580,7 @@ export type RepoEventLogsQuery = { }; export type RepoSettingsQueryVariables = Exact<{ - repoId: Scalars["String"]; + repoId: Scalars["String"]["input"]; }>; export type RepoSettingsQuery = { @@ -7730,8 +7818,8 @@ export type SpruceConfigQuery = { }; export type SystemLogsQueryVariables = Exact<{ - id: Scalars["String"]; - execution?: InputMaybe; + id: Scalars["String"]["input"]; + execution?: InputMaybe; }>; export type SystemLogsQuery = { @@ -7753,7 +7841,7 @@ export type SystemLogsQuery = { }; export type TaskAllExecutionsQueryVariables = Exact<{ - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }>; export type TaskAllExecutionsQuery = { @@ -7769,8 +7857,8 @@ export type TaskAllExecutionsQuery = { }; export type TaskEventLogsQueryVariables = Exact<{ - id: Scalars["String"]; - execution?: InputMaybe; + id: Scalars["String"]["input"]; + execution?: InputMaybe; }>; export type TaskEventLogsQuery = { @@ -7803,8 +7891,8 @@ export type TaskEventLogsQuery = { }; export type TaskFilesQueryVariables = Exact<{ - taskId: Scalars["String"]; - execution?: InputMaybe; + taskId: Scalars["String"]["input"]; + execution?: InputMaybe; }>; export type TaskFilesQuery = { @@ -7830,8 +7918,8 @@ export type TaskFilesQuery = { }; export type TaskLogsQueryVariables = Exact<{ - id: Scalars["String"]; - execution?: InputMaybe; + id: Scalars["String"]["input"]; + execution?: InputMaybe; }>; export type TaskLogsQuery = { @@ -7853,8 +7941,8 @@ export type TaskLogsQuery = { }; export type TaskNamesForBuildVariantQueryVariables = Exact<{ - projectIdentifier: Scalars["String"]; - buildVariant: Scalars["String"]; + projectIdentifier: Scalars["String"]["input"]; + buildVariant: Scalars["String"]["input"]; }>; export type TaskNamesForBuildVariantQuery = { @@ -7863,7 +7951,7 @@ export type TaskNamesForBuildVariantQuery = { }; export type TaskStatusesQueryVariables = Exact<{ - id: Scalars["String"]; + id: Scalars["String"]["input"]; }>; export type TaskStatusesQuery = { @@ -7877,7 +7965,7 @@ export type TaskStatusesQuery = { }; export type TaskTestSampleQueryVariables = Exact<{ - tasks: Array; + tasks: Array; filters: Array; }>; @@ -7893,13 +7981,13 @@ export type TaskTestSampleQuery = { }; export type TaskTestsQueryVariables = Exact<{ - id: Scalars["String"]; - execution?: InputMaybe; - pageNum?: InputMaybe; - limitNum?: InputMaybe; - statusList: Array; + id: Scalars["String"]["input"]; + execution?: InputMaybe; + pageNum?: InputMaybe; + limitNum?: InputMaybe; + statusList: Array; sort?: InputMaybe>; - testName: Scalars["String"]; + testName: Scalars["String"]["input"]; }>; export type TaskTestsQuery = { @@ -7932,8 +8020,8 @@ export type TaskTestsQuery = { }; export type TaskQueryVariables = Exact<{ - taskId: Scalars["String"]; - execution?: InputMaybe; + taskId: Scalars["String"]["input"]; + execution?: InputMaybe; }>; export type TaskQuery = { @@ -8116,7 +8204,7 @@ export type TaskQuery = { }; export type UndispatchedTasksQueryVariables = Exact<{ - versionId: Scalars["String"]; + versionId: Scalars["String"]["input"]; }>; export type UndispatchedTasksQuery = { @@ -8197,7 +8285,7 @@ export type UserQuery = { }; export type VersionTaskDurationsQueryVariables = Exact<{ - versionId: Scalars["String"]; + versionId: Scalars["String"]["input"]; taskFilterOptions: TaskFilterOptions; }>; @@ -8234,7 +8322,7 @@ export type VersionTaskDurationsQuery = { }; export type VersionTasksQueryVariables = Exact<{ - versionId: Scalars["String"]; + versionId: Scalars["String"]["input"]; taskFilterOptions: TaskFilterOptions; }>; @@ -8286,7 +8374,7 @@ export type VersionTasksQuery = { }; export type VersionQueryVariables = Exact<{ - id: Scalars["String"]; + id: Scalars["String"]["input"]; }>; export type VersionQuery = { @@ -8409,15 +8497,15 @@ export type ViewableProjectRefsQuery = { }; export type HostsQueryVariables = Exact<{ - hostId?: InputMaybe; - distroId?: InputMaybe; - currentTaskId?: InputMaybe; - statuses?: InputMaybe>; - startedBy?: InputMaybe; + hostId?: InputMaybe; + distroId?: InputMaybe; + currentTaskId?: InputMaybe; + statuses?: InputMaybe>; + startedBy?: InputMaybe; sortBy?: InputMaybe; sortDir?: InputMaybe; - page?: InputMaybe; - limit?: InputMaybe; + page?: InputMaybe; + limit?: InputMaybe; }>; export type HostsQuery = { @@ -8454,7 +8542,7 @@ export type HostsQuery = { }; export type ProjectHealthViewQueryVariables = Exact<{ - identifier: Scalars["String"]; + identifier: Scalars["String"]["input"]; }>; export type ProjectHealthViewQuery = { @@ -8470,7 +8558,7 @@ export type ProjectHealthViewQuery = { }; export type ProjectPatchesQueryVariables = Exact<{ - projectIdentifier: Scalars["String"]; + projectIdentifier: Scalars["String"]["input"]; patchesInput: PatchesInput; }>; @@ -8532,7 +8620,7 @@ export type SpawnExpirationInfoQuery = { }; export type SpawnTaskQueryVariables = Exact<{ - taskId: Scalars["String"]; + taskId: Scalars["String"]["input"]; }>; export type SpawnTaskQuery = { @@ -8577,7 +8665,7 @@ export type TaskQueueDistrosQuery = { }; export type UserDistroSettingsPermissionsQueryVariables = Exact<{ - distroId: Scalars["String"]; + distroId: Scalars["String"]["input"]; }>; export type UserDistroSettingsPermissionsQuery = { @@ -8594,7 +8682,7 @@ export type UserDistroSettingsPermissionsQuery = { }; export type UserPatchesQueryVariables = Exact<{ - userId: Scalars["String"]; + userId: Scalars["String"]["input"]; patchesInput: PatchesInput; }>; diff --git a/src/gql/queries/distro-events.graphql b/src/gql/queries/distro-events.graphql new file mode 100644 index 0000000000..8335b76832 --- /dev/null +++ b/src/gql/queries/distro-events.graphql @@ -0,0 +1,12 @@ +query DistroEvents($distroId: String!, $limit: Int, $before: Time) { + distroEvents(opts: { distroId: $distroId, limit: $limit, before: $before }) { + count + eventLogEntries { + after + before + data + timestamp + user + } + } +} diff --git a/src/gql/queries/index.ts b/src/gql/queries/index.ts index 2a80d744e7..69b2a98ba8 100644 --- a/src/gql/queries/index.ts +++ b/src/gql/queries/index.ts @@ -1,4 +1,5 @@ import GET_AWS_REGIONS from "./aws-regions.graphql"; +import DISTRO_EVENTS from "./distro-events.graphql"; import DISTRO_TASK_QUEUE from "./distro-task-queue.graphql"; import DISTRO from "./distro.graphql"; import GET_FAILED_TASK_STATUS_ICON_TOOLTIP from "./failed-task-status-icon-tooltip.graphql"; @@ -79,6 +80,7 @@ import USER_SUBSCRIPTIONS from "./user-subscriptions.graphql"; export { DISTRO, + DISTRO_EVENTS, DISTRO_TASK_QUEUE, GET_AGENT_LOGS, GET_ALL_LOGS, diff --git a/src/hooks/tests/useBreadcrumbRoot.test.tsx b/src/hooks/tests/useBreadcrumbRoot.test.tsx index 75bb3bf622..60e61f84d2 100644 --- a/src/hooks/tests/useBreadcrumbRoot.test.tsx +++ b/src/hooks/tests/useBreadcrumbRoot.test.tsx @@ -1,10 +1,10 @@ import { InMemoryCache } from "@apollo/client"; import { MockedProvider } from "@apollo/client/testing"; -import { renderHook } from "@testing-library/react-hooks"; import { OtherUserQuery, OtherUserQueryVariables } from "gql/generated/types"; import { getUserMock } from "gql/mocks/getUser"; import { GET_OTHER_USER } from "gql/queries"; import { useBreadcrumbRoot } from "hooks"; +import { renderHook, waitFor } from "test_utils"; import { ApolloMock } from "types/gql"; const cache = new InMemoryCache({ @@ -29,24 +29,24 @@ const OtherUserProvider = ({ children }) => ( describe("useBreadcrumbRoot", () => { it("returns the correct breadcrumb root when the version is a patch belonging to current user", async () => { - const { result, waitForNextUpdate } = renderHook( + const { result } = renderHook( () => useBreadcrumbRoot(true, "admin", "spruce"), { wrapper: SameUserProvider } ); - await waitForNextUpdate(); - - expect(result.current.to).toBe("/user/admin/patches"); + await waitFor(() => { + expect(result.current.to).toBe("/user/admin/patches"); + }); expect(result.current.text).toBe("My Patches"); }); it("returns the correct breadcrumb root when the version is a patch belonging to other user", async () => { - const { result, waitForNextUpdate } = renderHook( + const { result } = renderHook( () => useBreadcrumbRoot(true, "john.doe", "spruce"), { wrapper: OtherUserProvider } ); - await waitForNextUpdate(); - - expect(result.current.to).toBe("/user/john.doe/patches"); + await waitFor(() => { + expect(result.current.to).toBe("/user/john.doe/patches"); + }); expect(result.current.text).toBe("John Doe's Patches"); }); diff --git a/src/hooks/tests/useDisableSpawnExpirationCheckbox.test.tsx b/src/hooks/tests/useDisableSpawnExpirationCheckbox.test.tsx index c679f2a2ad..1cd04fbee0 100644 --- a/src/hooks/tests/useDisableSpawnExpirationCheckbox.test.tsx +++ b/src/hooks/tests/useDisableSpawnExpirationCheckbox.test.tsx @@ -1,5 +1,4 @@ import { MockedProvider } from "@apollo/client/testing"; -import { renderHook } from "@testing-library/react-hooks"; import { MyHostsQuery, MyHostsQueryVariables, @@ -8,6 +7,7 @@ import { } from "gql/generated/types"; import { getSpruceConfigMock } from "gql/mocks/getSpruceConfig"; import { GET_MY_VOLUMES, GET_MY_HOSTS } from "gql/queries"; +import { renderHook } from "test_utils"; import { ApolloMock } from "types/gql"; import { useDisableSpawnExpirationCheckbox } from ".."; @@ -20,18 +20,17 @@ const getProvider = (mocks) => { describe("useDisableSpawnExpirationCheckbox", () => { it("should return true when the user already has the maximum unexpirable volumes and a target item is not supplied.", async () => { - const { result, waitForNextUpdate } = renderHook( + const { result } = renderHook( () => useDisableSpawnExpirationCheckbox(true), { wrapper: getProvider(mocks), } ); - await waitForNextUpdate(); expect(result.current).toBeTruthy(); }); it("should return false when when the user has the maximum number of unexpirable volumes and the target item is unexpirable.", async () => { - const { result, waitForNextUpdate } = renderHook( + const { result } = renderHook( () => useDisableSpawnExpirationCheckbox(true, { ...volume, @@ -39,12 +38,11 @@ describe("useDisableSpawnExpirationCheckbox", () => { }), { wrapper: getProvider(mocks) } ); - await waitForNextUpdate(); expect(result.current).toBeFalsy(); }); it("should return true when the user has the maximum number of unexpirable volumes and the target item is expirable.", async () => { - const { result, waitForNextUpdate } = renderHook( + const { result } = renderHook( () => useDisableSpawnExpirationCheckbox(true, { ...volume, @@ -54,21 +52,19 @@ describe("useDisableSpawnExpirationCheckbox", () => { wrapper: getProvider(mocks), } ); - await waitForNextUpdate(); expect(result.current).toBeTruthy(); }); it("should return true when the user has the maximum number of hosts and a target item is not supplied.", async () => { - const { result, waitForNextUpdate } = renderHook( + const { result } = renderHook( () => useDisableSpawnExpirationCheckbox(false), { wrapper: getProvider(mocks) } ); - await waitForNextUpdate(); expect(result.current).toBeTruthy(); }); it("should return false when when user has the maximum number of unexpirable hosts and the target item is unexpirable.", async () => { - const { result, waitForNextUpdate } = renderHook( + const { result } = renderHook( () => useDisableSpawnExpirationCheckbox(false, { ...host, @@ -78,12 +74,11 @@ describe("useDisableSpawnExpirationCheckbox", () => { wrapper: getProvider(mocks), } ); - await waitForNextUpdate(); expect(result.current).toBeFalsy(); }); it("should return false when when user has the maximum number of unexpirable hosts and the target item is expirable.", async () => { - const { result, waitForNextUpdate } = renderHook( + const { result } = renderHook( () => useDisableSpawnExpirationCheckbox(false, { ...host, @@ -93,7 +88,6 @@ describe("useDisableSpawnExpirationCheckbox", () => { wrapper: getProvider(mocks), } ); - await waitForNextUpdate(); expect(result.current).toBeTruthy(); }); }); diff --git a/src/hooks/tests/useGetUserPatchesPageTitleAndLink.test.tsx b/src/hooks/tests/useGetUserPatchesPageTitleAndLink.test.tsx index c00f7ca728..50a42a2448 100644 --- a/src/hooks/tests/useGetUserPatchesPageTitleAndLink.test.tsx +++ b/src/hooks/tests/useGetUserPatchesPageTitleAndLink.test.tsx @@ -1,8 +1,8 @@ import { MockedProvider } from "@apollo/client/testing"; -import { renderHook } from "@testing-library/react-hooks"; import { OtherUserQuery, OtherUserQueryVariables } from "gql/generated/types"; import { GET_OTHER_USER } from "gql/queries"; import { useGetUserPatchesPageTitleAndLink } from "hooks"; +import { renderHook, waitFor } from "test_utils"; import { ApolloMock } from "types/gql"; const mocks: ApolloMock[] = [ @@ -68,36 +68,35 @@ const Provider = ({ children }) => ( describe("useGetUserPatchesPageTitleAndLink", () => { it("return correct title and link when the userId passed into the hook parameter is that of the logged in user", async () => { - const { result, waitForNextUpdate } = renderHook( + const { result } = renderHook( () => useGetUserPatchesPageTitleAndLink("admin"), { wrapper: Provider } ); - - await waitForNextUpdate(); - - expect(result.current.title).toBe("My Patches"); + await waitFor(() => { + expect(result.current.title).toBe("My Patches"); + }); expect(result.current.link).toBe("/user/admin/patches"); }); it("return correct title and link when the userId passed into the hook parameter is not that of the logged in user", async () => { - const { result, waitForNextUpdate } = renderHook( + const { result } = renderHook( () => useGetUserPatchesPageTitleAndLink("justin.mathew"), { wrapper: Provider } ); - - await waitForNextUpdate(); - - expect(result.current.title).toBe("Justin Mathew's Patches"); + await waitFor(() => { + expect(result.current.title).toBe("Justin Mathew's Patches"); + }); expect(result.current.link).toBe("/user/justin.mathew/patches"); }); it("return correct title and link when the userId passed into the hook parameter is not that of the logged in user and the display name of the other user ends with the letter 's'", async () => { - const { result, waitForNextUpdate } = renderHook( + const { result } = renderHook( () => useGetUserPatchesPageTitleAndLink("justin.mathews"), { wrapper: Provider } ); - await waitForNextUpdate(); - expect(result.current.title).toBe("Justin Mathews' Patches"); + await waitFor(() => { + expect(result.current.title).toBe("Justin Mathews' Patches"); + }); expect(result.current.link).toBe("/user/justin.mathews/patches"); }); }); diff --git a/src/hooks/tests/useLegacyUIURL.test.tsx b/src/hooks/tests/useLegacyUIURL.test.tsx index 4b81ca7213..372eefa139 100644 --- a/src/hooks/tests/useLegacyUIURL.test.tsx +++ b/src/hooks/tests/useLegacyUIURL.test.tsx @@ -1,5 +1,5 @@ -import { act, renderHook } from "@testing-library/react-hooks"; import { MemoryRouter, useNavigate } from "react-router-dom"; +import { act, renderHook } from "test_utils"; import { useLegacyUIURL } from "../useLegacyUIURL"; describe("useLegacyUIURL", () => { diff --git a/src/hooks/tests/useNetworkStatus.test.tsx b/src/hooks/tests/useNetworkStatus.test.tsx index 008d35b09c..4e159680fc 100644 --- a/src/hooks/tests/useNetworkStatus.test.tsx +++ b/src/hooks/tests/useNetworkStatus.test.tsx @@ -1,7 +1,7 @@ import { MockedProvider } from "@apollo/client/testing"; -import { act, renderHook } from "@testing-library/react-hooks/dom"; import { getUserMock } from "gql/mocks/getUser"; import { useNetworkStatus } from "hooks"; +import { act, renderHook } from "test_utils"; const Provider = ({ children }) => ( {children} diff --git a/src/hooks/tests/useOnClickOutside.test.tsx b/src/hooks/tests/useOnClickOutside.test.tsx index 48cdbd73e5..4da1b78220 100644 --- a/src/hooks/tests/useOnClickOutside.test.tsx +++ b/src/hooks/tests/useOnClickOutside.test.tsx @@ -1,32 +1,34 @@ import { createRef } from "react"; -import { renderHook } from "@testing-library/react-hooks"; import { useOnClickOutside } from "hooks"; -import { render, screen, userEvent } from "test_utils"; +import { renderHook, render, screen, userEvent } from "test_utils"; describe("useOnClickOutside", () => { describe("useOnClickOutside with 1 ref", () => { - it("executes callback when clicking outside element", () => { + it("executes callback when clicking outside element", async () => { + const user = userEvent.setup(); const body = document.body as HTMLElement; const callback = jest.fn(); const ref = createRef(); render(
Test ref
); renderHook(() => useOnClickOutside([ref], callback)); - userEvent.click(body); + await user.click(body); expect(callback).toHaveBeenCalledTimes(1); }); - it("does not execute callback when clicking inside element", () => { + it("does not execute callback when clicking inside element", async () => { + const user = userEvent.setup(); const callback = jest.fn(); const ref = createRef(); render(
Test ref
); renderHook(() => useOnClickOutside([ref], callback)); - userEvent.click(screen.getByText("Test ref")); + await user.click(screen.getByText("Test ref")); expect(callback).not.toHaveBeenCalled(); }); }); describe("useOnClickOutside with multiple refs", () => { - it("executes callback when clicking outside elements", () => { + it("executes callback when clicking outside elements", async () => { + const user = userEvent.setup(); const body = document.body as HTMLElement; const callback = jest.fn(); const ref1 = createRef(); @@ -39,10 +41,11 @@ describe("useOnClickOutside", () => { ); renderHook(() => useOnClickOutside([ref1, ref2], callback)); - userEvent.click(body); + await user.click(body); expect(callback).toHaveBeenCalledTimes(1); }); - it("does not execute callback when clicking inside elements", () => { + it("does not execute callback when clicking inside elements", async () => { + const user = userEvent.setup(); const callback = jest.fn(); const ref1 = createRef(); const ref2 = createRef(); @@ -54,9 +57,9 @@ describe("useOnClickOutside", () => { ); renderHook(() => useOnClickOutside([ref1, ref2], callback)); - userEvent.click(screen.getByText("Test ref 1")); + await user.click(screen.getByText("Test ref 1")); expect(callback).not.toHaveBeenCalled(); - userEvent.click(screen.getByText("Test ref 2")); + await user.click(screen.getByText("Test ref 2")); expect(callback).not.toHaveBeenCalled(); }); }); diff --git a/src/hooks/tests/usePageVisibility.test.tsx b/src/hooks/tests/usePageVisibility.test.tsx index a2b8334334..0444060b6c 100644 --- a/src/hooks/tests/usePageVisibility.test.tsx +++ b/src/hooks/tests/usePageVisibility.test.tsx @@ -1,7 +1,7 @@ import { MockedProvider } from "@apollo/client/testing"; -import { act, renderHook } from "@testing-library/react-hooks/dom"; import { getUserMock } from "gql/mocks/getUser"; import { usePageVisibility } from "hooks"; +import { act, renderHook } from "test_utils"; const Provider = ({ children }) => ( {children} diff --git a/src/hooks/tests/usePolling.test.tsx b/src/hooks/tests/usePolling.test.tsx index 007fb73d6d..0ed522aab9 100644 --- a/src/hooks/tests/usePolling.test.tsx +++ b/src/hooks/tests/usePolling.test.tsx @@ -1,9 +1,9 @@ import { MockedProvider } from "@apollo/client/testing"; -import { renderHook, act } from "@testing-library/react-hooks/dom"; import Cookie from "js-cookie"; import { FASTER_POLL_INTERVAL, DEFAULT_POLL_INTERVAL } from "constants/index"; import { getUserMock } from "gql/mocks/getUser"; import { usePolling } from "hooks"; +import { renderHook, act } from "test_utils"; jest.mock("js-cookie"); diff --git a/src/hooks/tests/useTableFilters/useTableFilters.test.tsx b/src/hooks/tests/useTableFilters/useTableFilters.test.tsx index cc4965a2ab..3e94ad1fe8 100644 --- a/src/hooks/tests/useTableFilters/useTableFilters.test.tsx +++ b/src/hooks/tests/useTableFilters/useTableFilters.test.tsx @@ -6,6 +6,7 @@ import { queryString } from "utils"; describe("useTableInputFilter", () => { it("accepts an input value", async () => { + const user = userEvent.setup(); render(, { route: "/hosts?hostId=123", path: "/hosts", @@ -16,10 +17,10 @@ describe("useTableInputFilter", () => { // starts with initial url params as value expect(input.value).toBe("123"); - userEvent.clear(input); - userEvent.type(input, "abc"); + await user.clear(input); + await user.type(input, "abc"); expect(input).toHaveValue("abc"); - userEvent.type(input, "{enter}"); + await user.type(input, "{enter}"); // returns updates value when component changes expect(input.value).toBe("abc"); @@ -27,31 +28,33 @@ describe("useTableInputFilter", () => { // updates url query params when update fn is called screen.getByText("host id from url: abc"); - userEvent.clear(input); + await user.clear(input); expect(input).toHaveValue(""); - userEvent.type(input, "{enter}"); + await user.type(input, "{enter}"); // resets url query params when reset fn is called expect(input.value).toBe(""); expect(screen.getByText("host id from url: N/A")).toBeInTheDocument(); }); - it("useTableInputFilter - trims whitespace from input value", () => { + it("useTableInputFilter - trims whitespace from input value", async () => { + const user = userEvent.setup(); render(, { route: "/hosts?hostId=123", path: "/hosts", }); const input = screen.getByPlaceholderText("Search ID") as HTMLInputElement; - userEvent.clear(input); - userEvent.type(input, " abc "); - userEvent.type(input, "{enter}"); + await user.clear(input); + await user.type(input, " abc "); + await user.type(input, "{enter}"); expect(screen.getByText("host id from url: abc")).toBeInTheDocument(); }); }); describe("useTableCheckboxFilter", () => { it("useTableCheckboxFilter", async () => { + const user = userEvent.setup(); render(, { route: "/hosts?statuses=running,terminated", path: "/hosts", @@ -69,7 +72,7 @@ describe("useTableCheckboxFilter", () => { expect(terminatedCheckbox.checked).toBe(true); // returns updates value when component changes - userEvent.click(runningCheckbox); + await user.click(screen.getByText("Running")); // LeafyGreen checkbox has pointer-events: none so click on the label instead. // updates url query params when update fn is called expect(runningCheckbox.checked).toBe(false); @@ -80,7 +83,7 @@ describe("useTableCheckboxFilter", () => { ).toBeInTheDocument(); // resets url query params when reset fn is called - userEvent.click(terminatedCheckbox); + await user.click(screen.getByText("Terminated")); // LeafyGreen checkbox has pointer-events: none so click on the label instead. expect(runningCheckbox.checked).toBe(false); expect(terminatedCheckbox.checked).toBe(false); diff --git a/src/hooks/tests/useUpdateUrlSortParamOnTableChange/useUpdateUrlSortParamOnTableChange.test.tsx b/src/hooks/tests/useUpdateUrlSortParamOnTableChange/useUpdateUrlSortParamOnTableChange.test.tsx index 44078aa6c3..3debd0c052 100644 --- a/src/hooks/tests/useUpdateUrlSortParamOnTableChange/useUpdateUrlSortParamOnTableChange.test.tsx +++ b/src/hooks/tests/useUpdateUrlSortParamOnTableChange/useUpdateUrlSortParamOnTableChange.test.tsx @@ -16,7 +16,8 @@ describe("useUpdateUrlSortParamOnTableChange", () => { matchMedia.clear(); }); - it("toggles table headers when clicked", () => { + it("toggles table headers when clicked", async () => { + const user = userEvent.setup(); render(, { route: "/hosts", path: "/hosts", @@ -25,22 +26,22 @@ describe("useUpdateUrlSortParamOnTableChange", () => { const idHeader = screen.getByText("ID"); const statusHeader = screen.getByText("Status"); - userEvent.click(idHeader); + await user.click(idHeader); expect(screen.getByText("sortBy: ID")).toBeInTheDocument(); expect(screen.getByText("sortDir: ASC")).toBeInTheDocument(); - userEvent.click(statusHeader); + await user.click(statusHeader); expect(screen.getByText("sortBy: STATUS")).toBeInTheDocument(); expect(screen.getByText("sortDir: ASC")).toBeInTheDocument(); - userEvent.click(statusHeader); + await user.click(statusHeader); expect(screen.getByText("sortBy: STATUS")).toBeInTheDocument(); expect(screen.getByText("sortDir: DESC")).toBeInTheDocument(); - userEvent.click(statusHeader); + await user.click(statusHeader); expect(screen.getByText("sortBy: none")).toBeInTheDocument(); expect(screen.getByText("sortDir: none")).toBeInTheDocument(); diff --git a/src/hooks/tests/useUpsertQueryParams.test.tsx b/src/hooks/tests/useUpsertQueryParams.test.tsx index e56cf97231..850639243c 100644 --- a/src/hooks/tests/useUpsertQueryParams.test.tsx +++ b/src/hooks/tests/useUpsertQueryParams.test.tsx @@ -33,65 +33,67 @@ const Content = () => { describe("useUpsertQueryParams", () => { it("renders normally and doesn't affect the url", () => { const { router } = renderWithRouterMatch(); - expect(router.state.location.search).toBe(""); }); - it("should add input query params to the url if none exist", () => { + it("should add input query params to the url if none exist", async () => { + const user = userEvent.setup(); const { router } = renderWithRouterMatch(); const category = screen.queryByDataCy("category"); const value = screen.queryByDataCy("value"); - userEvent.type(category, "category"); - userEvent.type(value, "value"); - userEvent.click(screen.queryByDataCy("submit")); - + await user.type(category, "category"); + await user.type(value, "value"); + await user.click(screen.queryByDataCy("submit")); expect(router.state.location.search).toBe(`?category=value`); }); - it("should add multiple input filters to the same key as query params", () => { + it("should add multiple input filters to the same key as query params", async () => { + const user = userEvent.setup(); const { router } = renderWithRouterMatch(); const category = screen.queryByDataCy("category"); const value = screen.queryByDataCy("value"); - userEvent.type(category, "category"); - userEvent.type(value, "value1"); - userEvent.click(screen.queryByDataCy("submit")); + await user.type(category, "category"); + await user.type(value, "value1"); + await user.click(screen.queryByDataCy("submit")); expect(router.state.location.search).toBe(`?category=value1`); - userEvent.clear(value); - userEvent.type(value, "value2"); - userEvent.click(screen.queryByDataCy("submit")); + await user.clear(value); + await user.type(value, "value2"); + await user.click(screen.queryByDataCy("submit")); expect(router.state.location.search).toBe(`?category=value1,value2`); }); - it("should not allow duplicate input filters for the same key as query params", () => { + it("should not allow duplicate input filters for the same key as query params", async () => { + const user = userEvent.setup(); const { router } = renderWithRouterMatch(); const category = screen.queryByDataCy("category"); const value = screen.queryByDataCy("value"); - userEvent.type(category, "category"); - userEvent.type(value, "value1"); - userEvent.click(screen.queryByDataCy("submit")); + await user.type(category, "category"); + await user.type(value, "value1"); + await user.click(screen.queryByDataCy("submit")); expect(router.state.location.search).toBe(`?category=value1`); - userEvent.clear(value); - userEvent.type(value, "value1"); - userEvent.click(screen.queryByDataCy("submit")); + await user.clear(value); + await user.type(value, "value1"); + await user.click(screen.queryByDataCy("submit")); expect(router.state.location.search).toBe(`?category=value1`); }); it("should allow multiple input filters for different keys as query params", async () => { + const user = userEvent.setup(); const { router } = renderWithRouterMatch(); const category = screen.queryByDataCy("category"); const value = screen.queryByDataCy("value"); - userEvent.type(category, "category"); - userEvent.type(value, "value1"); - userEvent.click(screen.queryByDataCy("submit")); + await user.type(category, "category"); + await user.type(value, "value1"); + await user.click(screen.queryByDataCy("submit")); expect(router.state.location.search).toBe(`?category=value1`); - userEvent.clear(category); - userEvent.type(category, "category2"); - userEvent.click(screen.queryByDataCy("submit")); + await user.clear(category); + await user.type(category, "category2"); + await user.click(screen.queryByDataCy("submit")); expect(router.state.location.search).toBe( `?category=value1&category2=value1` ); diff --git a/src/hooks/tests/useVersionStatusSelect.test.ts b/src/hooks/tests/useVersionStatusSelect.test.ts index 34493e9ca0..2b7ced9beb 100644 --- a/src/hooks/tests/useVersionStatusSelect.test.ts +++ b/src/hooks/tests/useVersionStatusSelect.test.ts @@ -1,5 +1,5 @@ -import { renderHook, act } from "@testing-library/react-hooks"; import { useVersionTaskStatusSelect } from "hooks"; +import { renderHook, act } from "test_utils"; const allFalse = { evergreen_lint_generate_lint: false, diff --git a/src/hooks/useDimensions/useDimensions.test.ts b/src/hooks/useDimensions/useDimensions.test.ts index 09fb0897a3..ec28421a0d 100644 --- a/src/hooks/useDimensions/useDimensions.test.ts +++ b/src/hooks/useDimensions/useDimensions.test.ts @@ -1,5 +1,5 @@ -import { act, renderHook } from "@testing-library/react-hooks"; import { useDimensions } from "hooks/useDimensions"; +import { act, renderHook } from "test_utils"; describe("useDimensions", () => { let listener; diff --git a/src/hooks/useIntersectionObserver/useIntersectionObserver.test.ts b/src/hooks/useIntersectionObserver/useIntersectionObserver.test.ts index a23e7f623d..58223a2239 100644 --- a/src/hooks/useIntersectionObserver/useIntersectionObserver.test.ts +++ b/src/hooks/useIntersectionObserver/useIntersectionObserver.test.ts @@ -1,4 +1,4 @@ -import { renderHook } from "@testing-library/react-hooks"; +import { renderHook } from "test_utils"; import useIntersectionObserver from "."; describe("useIntersectionObserver", () => { diff --git a/src/hooks/useKeyboardShortcut/useKeyboardShortcut.test.tsx b/src/hooks/useKeyboardShortcut/useKeyboardShortcut.test.tsx index c57dc8d72e..2a55ecea11 100644 --- a/src/hooks/useKeyboardShortcut/useKeyboardShortcut.test.tsx +++ b/src/hooks/useKeyboardShortcut/useKeyboardShortcut.test.tsx @@ -1,14 +1,11 @@ -/* eslint-disable testing-library/no-node-access */ -import { renderHook } from "@testing-library/react-hooks"; import { CharKey, ModifierKey } from "constants/keys"; -import { render, screen, userEvent } from "test_utils"; +import { renderHook, render, screen, userEvent } from "test_utils"; import useKeyboardShortcut from "."; -const { click, type } = userEvent; - describe("useKeyboardShortcut", () => { describe("multiple keys", () => { - it("should call the callback only when the exact shortcut keys are pressed", () => { + it("should call the callback only when the exact shortcut keys are pressed", async () => { + const user = userEvent.setup(); const callback = jest.fn(); renderHook(() => useKeyboardShortcut( @@ -16,17 +13,18 @@ describe("useKeyboardShortcut", () => { callback ) ); - type(document.body, "{ctrl}"); + await user.keyboard("{Control}"); expect(callback).toHaveBeenCalledTimes(0); - type(document.body, "{a}"); + await user.keyboard("{a}"); expect(callback).toHaveBeenCalledTimes(0); - type(document.body, "{ctrl}{shift}{a}{/ctrl}{/shift}"); + await user.keyboard("{Control>}{Shift>}{a}{/Control}{/Shift}"); expect(callback).toHaveBeenCalledTimes(0); - type(document.body, "{ctrl}{a}{/ctrl}"); + await user.keyboard("{Control>}{a}{/Control}"); expect(callback).toHaveBeenCalledTimes(1); }); - it("should not call the callback if an input element has focus", () => { + it("should not call the callback if an input element has focus", async () => { + const user = userEvent.setup(); const callback = jest.fn(); renderHook(() => useKeyboardShortcut( @@ -36,40 +34,43 @@ describe("useKeyboardShortcut", () => { ); render(); - click(screen.getByDataCy("test-input")); + await user.click(screen.getByDataCy("test-input")); expect(screen.getByDataCy("test-input")).toHaveFocus(); - type(document.activeElement, "{ctrl}a{/ctrl}"); + await user.keyboard("{Control>}{a}{/Control}"); expect(callback).toHaveBeenCalledTimes(0); - expect(screen.getByDataCy("test-input")).toHaveValue("a"); + expect(screen.getByDataCy("test-input")).toHaveValue(""); }); }); describe("single key", () => { - it("should call the callback only when the exact shortcut key is pressed", () => { + it("should call the callback only when the exact shortcut key is pressed", async () => { + const user = userEvent.setup(); const callback = jest.fn(); renderHook(() => useKeyboardShortcut({ charKey: CharKey.A }, callback)); - type(document.activeElement, "{ctrl}{A}{/ctrl}"); + await user.keyboard("{Control>}{A}{/Control}"); expect(callback).toHaveBeenCalledTimes(0); - type(document.activeElement, "{ctrl}{shift}{a}{/ctrl}{/shift}"); + await user.keyboard("{Control>}{Shift>}{a}{/Control}{/Shift}"); expect(callback).toHaveBeenCalledTimes(0); - type(document.activeElement, "{a}"); + await user.keyboard("{a}"); expect(callback).toHaveBeenCalledTimes(1); }); - it("should not call the callback if an input element has focus", () => { + it("should not call the callback if an input element has focus", async () => { + const user = userEvent.setup(); const callback = jest.fn(); renderHook(() => useKeyboardShortcut({ charKey: CharKey.A }, callback)); render(); - click(screen.getByDataCy("test-input")); + await user.click(screen.getByDataCy("test-input")); expect(screen.getByDataCy("test-input")).toHaveFocus(); - type(document.activeElement, "a"); + await user.keyboard("{a}"); expect(callback).toHaveBeenCalledTimes(0); expect(screen.getByDataCy("test-input")).toHaveValue("a"); }); }); - it("should call the callback if an input element has focus and ignoreFocus is enabled", () => { + it("should call the callback if an input element has focus and ignoreFocus is enabled", async () => { + const user = userEvent.setup(); const callback = jest.fn(); renderHook(() => useKeyboardShortcut( @@ -81,13 +82,14 @@ describe("useKeyboardShortcut", () => { ) ); render(); - click(screen.getByDataCy("test-input")); + await user.click(screen.getByDataCy("test-input")); expect(screen.getByDataCy("test-input")).toHaveFocus(); - type(document.activeElement, "{ctrl}{a}{/ctrl}"); + await user.keyboard("{Control>}{a}{/Control}"); expect(callback).toHaveBeenCalledTimes(1); }); - it("should not call the callback if the component is disabled", () => { + it("should not call the callback if the component is disabled", async () => { + const user = userEvent.setup(); const callback = jest.fn(); renderHook(() => useKeyboardShortcut( @@ -98,7 +100,7 @@ describe("useKeyboardShortcut", () => { } ) ); - type(document.activeElement, "{a}"); + await user.keyboard("{a}"); expect(callback).toHaveBeenCalledTimes(0); }); diff --git a/src/hooks/useKonamiCode/useKonamiCode.test.tsx b/src/hooks/useKonamiCode/useKonamiCode.test.tsx index 6dab243097..0bd09fbcad 100644 --- a/src/hooks/useKonamiCode/useKonamiCode.test.tsx +++ b/src/hooks/useKonamiCode/useKonamiCode.test.tsx @@ -1,12 +1,11 @@ import { MockedProvider } from "@apollo/client/testing"; import userEvent from "@testing-library/user-event"; -import { act } from "react-dom/test-utils"; import { RenderFakeToastContext } from "context/toast/__mocks__"; import { TaskQuery, TaskQueryVariables } from "gql/generated/types"; import { cache } from "gql/GQLWrapper"; import { taskQuery } from "gql/mocks/taskData"; import { GET_TASK } from "gql/queries"; -import { render, waitFor, screen } from "test_utils"; +import { render, screen } from "test_utils"; import useKonamiCode from "."; const KonamiCodeWrapper = ({ gqlCache }) => ( @@ -42,22 +41,16 @@ describe("useKonamiCode", () => { }, }); + const user = userEvent.setup(); const { Component, dispatchToast } = RenderFakeToastContext( ); - render(); - // eslint-disable-next-line testing-library/no-unnecessary-act - act(() => { - userEvent.type( - document.body, - "ArrowUpArrowUpArrowDownArrowDownArrowLeftArrowRightArrowLeftArrowRightba" - ); - }); - await waitFor(() => { - expect(audioPlayMock).toHaveBeenCalledTimes(1); - }); + await user.keyboard( + "{ArrowUp}{ArrowUp}{ArrowDown}{ArrowDown}{ArrowLeft}{ArrowRight}{ArrowLeft}{ArrowRight}{b}{a}" + ); + expect(audioPlayMock).toHaveBeenCalledTimes(1); expect(dispatchToast.success).toHaveBeenCalledWith( "To reset just refresh the page", true, @@ -90,22 +83,16 @@ describe("useKonamiCode", () => { }, }); + const user = userEvent.setup(); const { Component, dispatchToast } = RenderFakeToastContext( ); - render(); - // eslint-disable-next-line testing-library/no-unnecessary-act - act(() => { - userEvent.type( - document.body, - "ArrowUpArrowUpArrowDownArrowDownArrowLeftArrowRightArrowLeftArrowRightbb" - ); - }); - await waitFor(() => { - expect(audioPlayMock).toHaveBeenCalledTimes(0); - }); + await user.keyboard( + "{ArrowUp}{ArrowUp}{ArrowDown}{ArrowDown}{ArrowLeft}{ArrowRight}{ArrowLeft}{ArrowRight}{b}{b}" + ); + expect(audioPlayMock).toHaveBeenCalledTimes(0); expect(dispatchToast.success).not.toHaveBeenCalled(); expect( cache.extract()[ @@ -134,22 +121,18 @@ describe("useKonamiCode", () => { }, }); + const user = userEvent.setup(); const { Component, dispatchToast } = RenderFakeToastContext( ); - render(); - // eslint-disable-next-line testing-library/no-unnecessary-act - act(() => { - userEvent.type( - screen.getByRole("textbox"), - "ArrowUpArrowUpArrowDownArrowDownArrowLeftArrowRightArrowLeftArrowRightba" - ); - }); - await waitFor(() => { - expect(audioPlayMock).toHaveBeenCalledTimes(0); - }); + await user.type( + screen.getByRole("textbox"), + "{ArrowUp}{ArrowUp}{ArrowDown}{ArrowDown}{ArrowLeft}{ArrowRight}{ArrowLeft}{ArrowRight}{b}{a}" + ); + expect(screen.getByRole("textbox")).toHaveValue("ba"); + expect(audioPlayMock).toHaveBeenCalledTimes(0); expect(dispatchToast.success).not.toHaveBeenCalled(); expect( cache.extract()[ diff --git a/src/hooks/useQueryParam/useQueryParam.test.tsx b/src/hooks/useQueryParam/useQueryParam.test.tsx index f326801ea2..1c2ac31c2a 100644 --- a/src/hooks/useQueryParam/useQueryParam.test.tsx +++ b/src/hooks/useQueryParam/useQueryParam.test.tsx @@ -1,5 +1,5 @@ -import { act, renderHook } from "@testing-library/react-hooks"; import { MemoryRouter } from "react-router-dom"; +import { act, renderHook } from "test_utils"; import { useQueryParam, useQueryParams } from "."; describe("useQueryParams", () => { diff --git a/src/hooks/useResize/useResize.test.ts b/src/hooks/useResize/useResize.test.ts index 266006b188..6fd280801e 100644 --- a/src/hooks/useResize/useResize.test.ts +++ b/src/hooks/useResize/useResize.test.ts @@ -1,4 +1,4 @@ -import { renderHook, act } from "@testing-library/react-hooks"; +import { renderHook, act } from "test_utils"; import { useResize } from "."; describe("useResize", () => { diff --git a/src/hooks/useTabShortcut/useTabShortcut.test.ts b/src/hooks/useTabShortcut/useTabShortcut.test.ts index c0271c1663..868fa17a7d 100644 --- a/src/hooks/useTabShortcut/useTabShortcut.test.ts +++ b/src/hooks/useTabShortcut/useTabShortcut.test.ts @@ -1,51 +1,49 @@ -/* eslint-disable testing-library/no-node-access */ -import { renderHook } from "@testing-library/react-hooks"; -import { userEvent } from "test_utils"; +import { renderHook, userEvent } from "test_utils"; import { useTabShortcut } from "."; -const { type } = userEvent; - describe("useTabShortcut", () => { - it("should call setSelectedTab with the next tab index when the 'j' key is pressed", () => { + it("should call setSelectedTab with the next tab index when the 'j' key is pressed", async () => { + const user = userEvent.setup(); const setSelectedTab = jest.fn(); let currentTab = 1; const { rerender } = renderHook(() => useTabShortcut({ setSelectedTab, currentTab, numTabs: 4 }) ); - type(document.body, "j"); + await user.keyboard("{j}"); expect(setSelectedTab).toHaveBeenCalledWith(2); currentTab = 2; rerender(); - type(document.body, "j"); + await user.keyboard("{j}"); expect(setSelectedTab).toHaveBeenCalledWith(3); currentTab = 3; rerender(); - type(document.body, "j"); + await user.keyboard("{j}"); expect(setSelectedTab).toHaveBeenCalledWith(0); currentTab = 0; rerender(); - type(document.body, "j"); + await user.keyboard("{j}"); expect(setSelectedTab).toHaveBeenCalledWith(1); }); - it("should call setSelectedTab with the previous tab index when the 'k' key is pressed", () => { + it("should call setSelectedTab with the previous tab index when the 'k' key is pressed", async () => { + const user = userEvent.setup(); const setSelectedTab = jest.fn(); let currentTab = 1; const { rerender } = renderHook(() => useTabShortcut({ setSelectedTab, currentTab, numTabs: 4 }) ); - type(document.body, "k"); + await user.keyboard("{k}"); expect(setSelectedTab).toHaveBeenCalledWith(0); currentTab = 0; rerender(); - type(document.body, "k"); + await user.keyboard("{k}"); expect(setSelectedTab).toHaveBeenCalledWith(3); currentTab = 3; rerender(); - type(document.body, "k"); + await user.keyboard("{k}"); expect(setSelectedTab).toHaveBeenCalledWith(2); currentTab = 2; rerender(); - type(document.body, "k"); + await user.keyboard("{k}"); expect(setSelectedTab).toHaveBeenCalledWith(1); }); }); diff --git a/src/pages/commits/ActiveCommits/BuildVariantCard/BuildVariantCard.test.tsx b/src/pages/commits/ActiveCommits/BuildVariantCard/BuildVariantCard.test.tsx index 800ec3034f..0b940d446c 100644 --- a/src/pages/commits/ActiveCommits/BuildVariantCard/BuildVariantCard.test.tsx +++ b/src/pages/commits/ActiveCommits/BuildVariantCard/BuildVariantCard.test.tsx @@ -3,12 +3,7 @@ import { injectGlobalDimStyle, removeGlobalDimStyle, } from "pages/commits/ActiveCommits/utils"; -import { - renderWithRouterMatch as render, - screen, - userEvent, - waitFor, -} from "test_utils"; +import { renderWithRouterMatch as render, screen, userEvent } from "test_utils"; import { BuildVariantCard } from "."; jest.mock("../utils"); @@ -37,6 +32,7 @@ describe("buildVariantCard", () => { (removeGlobalDimStyle as jest.Mock).mockImplementationOnce(() => {}); + const user = userEvent.setup(); render( { ); - userEvent.hover(screen.queryByDataCy("build-variant-icon-container")); - await waitFor(() => { - expect(injectGlobalDimStyle).toHaveBeenCalledTimes(1); - }); - - userEvent.unhover(screen.queryByDataCy("build-variant-icon-container")); - await waitFor(() => { - expect(removeGlobalDimStyle).toHaveBeenCalledTimes(1); - }); + await user.hover(screen.queryByDataCy("build-variant-icon-container")); + expect(injectGlobalDimStyle).toHaveBeenCalledTimes(1); + await user.unhover(screen.queryByDataCy("build-variant-icon-container")); + expect(removeGlobalDimStyle).toHaveBeenCalledTimes(1); }); }); diff --git a/src/pages/commits/ActiveCommits/BuildVariantCard/WaterfallTaskStatusIcon/WaterfallTaskStatusIcon.test.tsx b/src/pages/commits/ActiveCommits/BuildVariantCard/WaterfallTaskStatusIcon/WaterfallTaskStatusIcon.test.tsx index f5ce09d06d..ddeb0d5c2f 100644 --- a/src/pages/commits/ActiveCommits/BuildVariantCard/WaterfallTaskStatusIcon/WaterfallTaskStatusIcon.test.tsx +++ b/src/pages/commits/ActiveCommits/BuildVariantCard/WaterfallTaskStatusIcon/WaterfallTaskStatusIcon.test.tsx @@ -43,8 +43,9 @@ const Content = ({ ); describe("waterfallTaskStatusIcon", () => { it("tooltip should contain task name, duration, list of failing test names and additonal test count", async () => { + const user = userEvent.setup(); render(); - userEvent.hover(screen.queryByDataCy("waterfall-task-status-icon")); + await user.hover(screen.queryByDataCy("waterfall-task-status-icon")); await waitFor(() => { expect( screen.queryByDataCy("waterfall-task-status-icon-tooltip") @@ -80,6 +81,7 @@ describe("waterfallTaskStatusIcon", () => { }); it("should call the appropriate functions on hover and unhover", async () => { + const user = userEvent.setup(); (injectGlobalHighlightStyle as jest.Mock).mockImplementationOnce( (taskIdentifier: string) => { Promise.resolve(taskIdentifier); @@ -88,16 +90,14 @@ describe("waterfallTaskStatusIcon", () => { (removeGlobalHighlightStyle as jest.Mock).mockImplementationOnce(() => {}); render(); - userEvent.hover(screen.queryByDataCy("waterfall-task-status-icon")); + await user.hover(screen.queryByDataCy("waterfall-task-status-icon")); await waitFor(() => { expect(injectGlobalHighlightStyle).toHaveBeenCalledTimes(1); }); expect(injectGlobalHighlightStyle).toHaveBeenCalledWith(props.identifier); - userEvent.unhover(screen.queryByDataCy("waterfall-task-status-icon")); - await waitFor(() => { - expect(removeGlobalHighlightStyle).toHaveBeenCalledTimes(1); - }); + await user.unhover(screen.queryByDataCy("waterfall-task-status-icon")); + expect(removeGlobalHighlightStyle).toHaveBeenCalledTimes(1); }); }); diff --git a/src/pages/commits/ActiveCommits/CommitBarChart/CommitBarChart.test.tsx b/src/pages/commits/ActiveCommits/CommitBarChart/CommitBarChart.test.tsx index 710bb53817..b06e7f568e 100644 --- a/src/pages/commits/ActiveCommits/CommitBarChart/CommitBarChart.test.tsx +++ b/src/pages/commits/ActiveCommits/CommitBarChart/CommitBarChart.test.tsx @@ -26,6 +26,7 @@ describe("commitChart", () => { }); it("hovering over the chart should open a tooltip", async () => { + const user = userEvent.setup(); render( { ); expect(screen.queryByDataCy("commit-chart-tooltip")).toBeNull(); - userEvent.hover(screen.queryByDataCy("commit-chart-container")); + await user.hover(screen.queryByDataCy("commit-chart-container")); await waitFor(() => { expect(screen.getByDataCy("commit-chart-tooltip")).toBeInTheDocument(); }); }); it("should show all umbrella statuses (normal and dimmed) and their counts", async () => { + const user = userEvent.setup(); render( { ); expect(screen.queryByDataCy("commit-chart-tooltip")).toBeNull(); - userEvent.hover(screen.queryByDataCy("commit-chart-container")); + await user.hover(screen.queryByDataCy("commit-chart-container")); await waitFor(() => { expect(screen.getByDataCy("commit-chart-tooltip")).toBeInTheDocument(); }); diff --git a/src/pages/commits/InactiveCommits/InactiveCommits.test.tsx b/src/pages/commits/InactiveCommits/InactiveCommits.test.tsx index c4d078b9bd..716ffbb6ba 100644 --- a/src/pages/commits/InactiveCommits/InactiveCommits.test.tsx +++ b/src/pages/commits/InactiveCommits/InactiveCommits.test.tsx @@ -35,16 +35,18 @@ describe("inactiveCommitButton", () => { }); it("clicking on the button should open a tooltip", async () => { + const user = userEvent.setup(); render(); expect(screen.queryByDataCy("inactive-commits-tooltip")).toBeNull(); - userEvent.click(screen.queryByDataCy("inactive-commits-button")); - await waitFor(() => - expect(screen.queryByDataCy("inactive-commits-tooltip")).toBeVisible() - ); + await user.click(screen.queryByDataCy("inactive-commits-button")); + await waitFor(() => { + expect(screen.queryByDataCy("inactive-commits-tooltip")).toBeVisible(); + }); }); it("should show all inactive commits if there are 3 or less commits", async () => { + const user = userEvent.setup(); render( { ); expect(screen.queryByDataCy("inactive-commits-tooltip")).toBeNull(); - userEvent.click(screen.queryByDataCy("inactive-commits-button")); - await waitFor(() => - expect(screen.queryByDataCy("inactive-commits-tooltip")).toBeVisible() - ); + await user.click(screen.queryByDataCy("inactive-commits-button")); + await waitFor(() => { + expect(screen.queryByDataCy("inactive-commits-tooltip")).toBeVisible(); + }); expect(screen.queryAllByDataCy("commit-text")).toHaveLength( MAX_COMMIT_COUNT - 1 ); @@ -63,13 +65,14 @@ describe("inactiveCommitButton", () => { }); it("should collapse commits if there are more than 3", async () => { + const user = userEvent.setup(); render(); expect(screen.queryByDataCy("inactive-commits-tooltip")).toBeNull(); - userEvent.click(screen.queryByDataCy("inactive-commits-button")); - await waitFor(() => - expect(screen.queryByDataCy("inactive-commits-tooltip")).toBeVisible() - ); + await user.click(screen.queryByDataCy("inactive-commits-button")); + await waitFor(() => { + expect(screen.queryByDataCy("inactive-commits-tooltip")).toBeVisible(); + }); expect(screen.queryAllByDataCy("commit-text")).toHaveLength( MAX_COMMIT_COUNT ); @@ -77,21 +80,22 @@ describe("inactiveCommitButton", () => { }); it("should open a modal when clicking on the hidden commits text", async () => { + const user = userEvent.setup(); render(); expect(screen.queryByDataCy("inactive-commits-tooltip")).toBeNull(); - userEvent.click(screen.queryByDataCy("inactive-commits-button")); - await waitFor(() => - expect(screen.queryByDataCy("inactive-commits-tooltip")).toBeVisible() - ); + await user.click(screen.queryByDataCy("inactive-commits-button")); + await waitFor(() => { + expect(screen.queryByDataCy("inactive-commits-tooltip")).toBeVisible(); + }); expect(screen.queryAllByDataCy("commit-text")).toHaveLength( MAX_COMMIT_COUNT ); expect(screen.queryByDataCy("inactive-commits-modal")).toBeNull(); - userEvent.click(screen.queryByDataCy("hidden-commits")); - await waitFor(() => - expect(screen.queryByDataCy("inactive-commits-modal")).toBeVisible() - ); + await user.click(screen.queryByDataCy("hidden-commits")); + await waitFor(() => { + expect(screen.queryByDataCy("inactive-commits-modal")).toBeVisible(); + }); }); it("should show unmatching label when there are filters applied", () => { diff --git a/src/pages/configurePatch/configurePatchCore/ConfigureTasks/ConfigureTasks.test.tsx b/src/pages/configurePatch/configurePatchCore/ConfigureTasks/ConfigureTasks.test.tsx index a1c01f5977..42a61d3f47 100644 --- a/src/pages/configurePatch/configurePatchCore/ConfigureTasks/ConfigureTasks.test.tsx +++ b/src/pages/configurePatch/configurePatchCore/ConfigureTasks/ConfigureTasks.test.tsx @@ -101,7 +101,8 @@ describe("configureTasks", () => { expect(checkbox).toBeInTheDocument(); expect(checkbox).toBePartiallyChecked(); }); - it("selecting a task should call setSelectedBuildVariantTasks with the correct arguments selecting only that task", () => { + it("selecting a task should call setSelectedBuildVariantTasks with the correct arguments selecting only that task", async () => { + const user = userEvent.setup(); const selectedBuildVariants = ["ubuntu2004"]; const setSelectedBuildVariantTasks = jest.fn(); render( @@ -124,12 +125,13 @@ describe("configureTasks", () => { expect(checkbox).toBeInTheDocument(); expect(checkbox).not.toBeChecked(); expect(setSelectedBuildVariantTasks).not.toHaveBeenCalled(); - checkbox.click(); + await user.click(screen.getByText("compile")); expect(setSelectedBuildVariantTasks).toHaveBeenCalledWith({ ubuntu2004: { compile: true, test: false }, }); }); - it("selecting all tasks should call setSelectedBuildVariantTasks with the correct arguments selecting all of the visible tasks in one variant", () => { + it("selecting all tasks should call setSelectedBuildVariantTasks with the correct arguments selecting all of the visible tasks in one variant", async () => { + const user = userEvent.setup(); const selectedBuildVariants = ["ubuntu2004"]; const setSelectedBuildVariantTasks = jest.fn(); render( @@ -155,13 +157,14 @@ describe("configureTasks", () => { expect(checkbox).toBeInTheDocument(); expect(checkbox).not.toBeChecked(); expect(setSelectedBuildVariantTasks).not.toHaveBeenCalled(); - checkbox.click(); + await user.click(screen.getByText("Select all tasks in this variant")); expect(setSelectedBuildVariantTasks).toHaveBeenCalledWith({ ubuntu2004: { compile: true, test: true }, ubuntu1804: { compile: false, lint: false }, }); }); - it("selecting a deduplicated task should call setSelectedBuildVariantTasks selecting the task in all variants", () => { + it("selecting a deduplicated task should call setSelectedBuildVariantTasks selecting the task in all variants", async () => { + const user = userEvent.setup(); const selectedBuildVariants = ["ubuntu2004", "ubuntu1804"]; const setSelectedBuildVariantTasks = jest.fn(); render( @@ -185,13 +188,14 @@ describe("configureTasks", () => { expect(checkbox).toBeInTheDocument(); expect(checkbox).not.toBeChecked(); expect(setSelectedBuildVariantTasks).not.toHaveBeenCalled(); - checkbox.click(); + await user.click(screen.getByText("compile")); expect(setSelectedBuildVariantTasks).toHaveBeenCalledWith({ ubuntu2004: { compile: true, test: false }, ubuntu1804: { compile: true, lint: false }, }); }); - it("selecting all tasks should call setSelectedBuildVariantTasks with the correct arguments selecting all of the visible tasks in multiple variants", () => { + it("selecting all tasks should call setSelectedBuildVariantTasks with the correct arguments selecting all of the visible tasks in multiple variants", async () => { + const user = userEvent.setup(); const selectedBuildVariants = ["ubuntu2004", "ubuntu1804"]; const setSelectedBuildVariantTasks = jest.fn(); render( @@ -217,13 +221,14 @@ describe("configureTasks", () => { expect(checkbox).toBeInTheDocument(); expect(checkbox).not.toBeChecked(); expect(setSelectedBuildVariantTasks).not.toHaveBeenCalled(); - checkbox.click(); + await user.click(screen.getByText("Select all tasks in these variants")); expect(setSelectedBuildVariantTasks).toHaveBeenCalledWith({ ubuntu2004: { compile: true, test: true }, ubuntu1804: { compile: true, lint: true }, }); }); - it("applying a search should filter the tasks", () => { + it("applying a search should filter the tasks", async () => { + const user = userEvent.setup(); const selectedBuildVariants = ["ubuntu2004", "ubuntu1804"]; render( { /> ); - userEvent.type(screen.getByDataCy("task-filter-input"), "compile"); + await user.type(screen.getByDataCy("task-filter-input"), "compile"); expect(screen.queryAllByDataCy("task-checkbox")).toHaveLength(1); const checkbox = screen.getByLabelText("compile"); expect(checkbox).toBeInTheDocument(); @@ -400,7 +405,8 @@ describe("configureTasks", () => { expect(screen.getByLabelText("test")).toBeInTheDocument(); expect(screen.getByLabelText("parsley")).toBeInTheDocument(); }); - it("selecting the entire alias calls setSelectedAliases with the correct arguments", () => { + it("selecting the entire alias calls setSelectedAliases with the correct arguments", async () => { + const user = userEvent.setup(); const selectedBuildVariants = ["parsley"]; const setSelectedBuildVariantTasks = jest.fn(); const setSelectedAliases = jest.fn(); @@ -436,7 +442,7 @@ describe("configureTasks", () => { /> ); expect(screen.getByLabelText("Add alias to patch")).toBeInTheDocument(); - screen.getByLabelText("Add alias to patch").click(); + await user.click(screen.getByText("Add alias to patch")); expect(setSelectedAliases).toHaveBeenCalledWith({ parsley: true, }); diff --git a/src/pages/configurePatch/configurePatchCore/__snapshots__/ConfigurePatchCore.stories.storyshot b/src/pages/configurePatch/configurePatchCore/__snapshots__/ConfigurePatchCore.stories.storyshot index 4442004d3a..a7935e823b 100644 --- a/src/pages/configurePatch/configurePatchCore/__snapshots__/ConfigurePatchCore.stories.storyshot +++ b/src/pages/configurePatch/configurePatchCore/__snapshots__/ConfigurePatchCore.stories.storyshot @@ -65,14 +65,16 @@ exports[`storybook Storyshots pages/configurePatch/configurePatchCore Configure
-

- Patch Metadata -

-
+
+

+ Patch Metadata +

+
+

@@ -291,7 +293,7 @@ exports[`storybook Storyshots pages/configurePatch/configurePatchCore Configure autocomplete="on" class="leafygreen-ui-6i61vl" data-cy="task-filter-input" - id="textinput-238" + id="textinput-236" placeholder="Search tasks" required="" type="text" @@ -307,17 +309,17 @@ exports[`storybook Storyshots pages/configurePatch/configurePatchCore Configure >