chore(site): Try to fix flake test (#6848)

This commit is contained in:
Bruno Quaresma
2023-03-29 16:10:04 -03:00
committed by GitHub
parent 90d18dd2e5
commit 175dde1c52
45 changed files with 318 additions and 529 deletions
+12
View File
@@ -32,6 +32,17 @@ plugins:
- react-hooks
- jest
- unicorn
- testing-library
overrides:
- files: ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)"]
extends: ["plugin:testing-library/react", "plugin:testing-library/dom"]
rules:
# Occasionally, we must traverse the DOM when querying for an element to
# avoid the performance costs that come with using selectors like ByRole.
# You can read more about these performance costs here:
# https://coder.com/docs/v2/latest/contributing/frontend#tests-getting-too-slow.
testing-library/no-node-access: off
testing-library/no-container: off
root: true
rules:
"@typescript-eslint/brace-style":
@@ -145,6 +156,7 @@ rules:
message: "Default React import not allowed",
},
]
settings:
react:
version: detect
+1
View File
@@ -5,6 +5,7 @@ import { addDecorator } from "node_modules/@storybook/react"
import { unstable_HistoryRouter as HistoryRouter } from "react-router-dom"
import { dark } from "../src/theme"
import "../src/theme/globalFonts"
import "../src/i18n"
addDecorator((story) => (
<ThemeProvider theme={dark}>
+3 -2
View File
@@ -53,6 +53,7 @@
"date-fns": "2.29.3",
"dayjs": "1.11.4",
"emoji-mart": "5.4.0",
"eslint-plugin-testing-library": "^5.10.2",
"eventsourcemock": "2.0.0",
"formik": "2.2.9",
"front-matter": "4.0.2",
@@ -97,8 +98,8 @@
"@storybook/react": "6.5.12",
"@swc/core": "1.3.38",
"@swc/jest": "0.2.24",
"@testing-library/jest-dom": "5.16.4",
"@testing-library/react": "13.4.0",
"@testing-library/jest-dom": "5.16.5",
"@testing-library/react": "14.0.0",
"@testing-library/user-event": "14.4.3",
"@types/jest": "29.4.0",
"@types/node": "14.18.22",
@@ -3,7 +3,7 @@ import {
MockWorkspace,
MockWorkspaceAgent,
MockWorkspaceApp,
} from "testHelpers/renderHelpers"
} from "testHelpers/entities"
import { AppLink, AppLinkProps } from "./AppLink"
export default {
@@ -1,4 +1,4 @@
import { fireEvent, render } from "@testing-library/react"
import { fireEvent, render, screen } from "@testing-library/react"
import { FC } from "react"
import { WrapperComponent } from "../../../testHelpers/renderHelpers"
import { ConfirmDialog, ConfirmDialogProps } from "./ConfirmDialog"
@@ -26,10 +26,10 @@ describe("ConfirmDialog", () => {
}
// When
const { getByRole } = render(<Helpers.Component {...props} />)
render(<Helpers.Component {...props} />)
// Then
expect(getByRole("dialog")).toBeDefined()
expect(screen.getByRole("dialog")).toBeDefined()
})
it("does not display cancel for info dialogs", () => {
@@ -43,10 +43,10 @@ describe("ConfirmDialog", () => {
}
// When
const { queryByText } = render(<Helpers.Component {...props} />)
render(<Helpers.Component {...props} />)
// Then
expect(queryByText("CANCEL")).toBeNull()
expect(screen.queryByText("CANCEL")).toBeNull()
})
it("can display cancel when normally hidden", () => {
@@ -61,10 +61,10 @@ describe("ConfirmDialog", () => {
}
// When
const { getByText } = render(<Helpers.Component {...props} />)
render(<Helpers.Component {...props} />)
// Then
expect(getByText("CANCEL")).toBeDefined()
expect(screen.getByText("CANCEL")).toBeDefined()
})
it("displays cancel for delete dialogs", () => {
@@ -79,10 +79,10 @@ describe("ConfirmDialog", () => {
}
// When
const { getByText } = render(<Helpers.Component {...props} />)
render(<Helpers.Component {...props} />)
// Then
expect(getByText("CANCEL")).toBeDefined()
expect(screen.getByText("CANCEL")).toBeDefined()
})
it("can hide cancel when normally visible", () => {
@@ -98,10 +98,10 @@ describe("ConfirmDialog", () => {
}
// When
const { queryByText } = render(<Helpers.Component {...props} />)
render(<Helpers.Component {...props} />)
// Then
expect(queryByText("CANCEL")).toBeNull()
expect(screen.queryByText("CANCEL")).toBeNull()
})
it("onClose is called when cancelled", () => {
@@ -116,8 +116,8 @@ describe("ConfirmDialog", () => {
}
// When
const { getByText } = render(<Helpers.Component {...props} />)
fireEvent.click(getByText("CANCEL"))
render(<Helpers.Component {...props} />)
fireEvent.click(screen.getByText("CANCEL"))
// Then
expect(onCloseMock).toBeCalledTimes(1)
@@ -138,8 +138,8 @@ describe("ConfirmDialog", () => {
}
// When
const { getByText } = render(<Helpers.Component {...props} />)
fireEvent.click(getByText("CONFIRM"))
render(<Helpers.Component {...props} />)
fireEvent.click(screen.getByText("CONFIRM"))
// Then
expect(onCloseMock).toBeCalledTimes(0)
@@ -1,6 +1,7 @@
import { action } from "@storybook/addon-actions"
import { Story } from "@storybook/react"
import { MockUser } from "../../../testHelpers/renderHelpers"
import { MockUser } from "testHelpers/entities"
import {
ResetPasswordDialog,
ResetPasswordDialogProps,
@@ -1,77 +0,0 @@
import { fireEvent, render, screen } from "@testing-library/react"
import { useFormik } from "formik"
import { FC } from "react"
import * as yup from "yup"
import { FormTextField, FormTextFieldProps } from "./FormTextField"
namespace Helpers {
export interface FormValues {
name: string
}
export const requiredValidationMsg = "required"
export const Component: FC<
React.PropsWithChildren<
Omit<FormTextFieldProps<FormValues>, "form" | "formFieldName">
>
> = (props) => {
const form = useFormik<FormValues>({
initialValues: {
name: "",
},
onSubmit: (values, helpers) => {
return helpers.setSubmitting(false)
},
validationSchema: yup.object({
name: yup.string().required(requiredValidationMsg),
}),
})
return (
<FormTextField<FormValues> {...props} form={form} formFieldName="name" />
)
}
}
describe("FormTextField", () => {
describe("helperText", () => {
it("uses helperText prop when there are no errors", () => {
// Given
const props = {
helperText: "testing",
}
// When
const { queryByText } = render(<Helpers.Component {...props} />)
// Then
expect(queryByText(props.helperText)).toBeDefined()
})
it("uses validation message when there are errors", () => {
// Given
const props = {}
// When
const { container } = render(<Helpers.Component {...props} />)
const el = container.firstChild
// Then
expect(el).toBeDefined()
expect(screen.queryByText(Helpers.requiredValidationMsg)).toBeNull()
// When
fireEvent.focus(el as Element)
// Then
expect(screen.queryByText(Helpers.requiredValidationMsg)).toBeNull()
// When
fireEvent.blur(el as Element)
// Then
expect(screen.queryByText(Helpers.requiredValidationMsg)).toBeDefined()
})
})
})
@@ -1,163 +0,0 @@
import TextField, { TextFieldProps } from "@material-ui/core/TextField"
import { FormikContextType } from "formik"
import { ReactElement } from "react"
import { PasswordField } from "../PasswordField/PasswordField"
/**
* FormFieldProps are required props for creating form fields using a factory.
*/
interface FormFieldProps<T> {
/**
* form is a reference to a form or subform and is used to compute common
* states such as error and helper text
*/
form: FormikContextType<T>
/**
* formFieldName is a field name associated with the form schema.
*/
formFieldName: keyof T
}
/**
* FormTextFieldProps extends form-related MUI TextFieldProps with Formik
* props. The passed in form is used to compute error states and configure
* change handlers. `formFieldName` represents the key of a Formik value
* that's associated to this component.
*/
export interface FormTextFieldProps<T>
extends Pick<
TextFieldProps,
| "autoComplete"
| "autoFocus"
| "children"
| "className"
| "disabled"
| "fullWidth"
| "helperText"
| "id"
| "InputLabelProps"
| "InputProps"
| "inputProps"
| "label"
| "margin"
| "multiline"
| "onChange"
| "placeholder"
| "required"
| "rows"
| "select"
| "SelectProps"
| "style"
| "type"
>,
FormFieldProps<T> {
/**
* eventTransform is an optional transformer on the event data before it is
* processed by formik.
*
* @example
* <FormTextField
* eventTransformer={(str) => {
* return str.replace(" ", "-")
* }}
* />
*/
eventTransform?: (value: string) => string
/**
* isPassword uses a PasswordField component when `true`; otherwise a
* TextField component is used.
*/
isPassword?: boolean
/**
* displayValueOverride allows displaying a different value in the field
* without changing the actual underlying value.
*/
displayValueOverride?: string
variant?: "outlined" | "filled" | "standard"
}
/**
* Factory function for creating a formik TextField
*
* @example
* interface FormValues {
* username: string
* }
*
* // Use the factory to create a FormTextField associated to this form
* const FormTextField = formTextFieldFactory<FormValues>()
*
* const MyComponent: React.FC = () => {
* const form = useFormik<FormValues>()
*
* return (
* <FormTextField
* form={form}
* formFieldName="username"
* fullWidth
* helperText="A unique name"
* label="Username"
* placeholder="Lorem Ipsum"
* required
* />
* )
* }
*/
export const FormTextField = <T,>({
children,
disabled,
displayValueOverride,
eventTransform,
form,
formFieldName,
helperText,
isPassword = false,
InputProps,
onChange,
type,
variant = "outlined",
...rest
}: FormTextFieldProps<T>): ReactElement => {
const isError =
form.touched[formFieldName] && Boolean(form.errors[formFieldName])
// Conversion to a string primitive is necessary as formFieldName is an in
// indexable type such as a string, number or enum.
const fieldId = String(formFieldName)
const Component = isPassword ? PasswordField : TextField
const inputType = isPassword ? undefined : type
return (
<Component
{...rest}
variant={variant}
disabled={disabled || form.isSubmitting}
error={isError}
helperText={isError ? form.errors[formFieldName]?.toString() : helperText}
id={fieldId}
InputProps={isPassword ? undefined : InputProps}
name={fieldId}
onBlur={form.handleBlur}
onChange={(e) => {
if (typeof onChange !== "undefined") {
onChange(e)
}
const event = e
if (
typeof eventTransform !== "undefined" &&
typeof event.target.value === "string"
) {
event.target.value = eventTransform(e.target.value)
}
form.handleChange(event)
}}
type={inputType}
value={displayValueOverride || form.values[formFieldName]}
>
{children}
</Component>
)
}
+1 -1
View File
@@ -5,7 +5,7 @@ import { rest } from "msw"
import {
MockEntitlementsWithAuditLog,
MockMemberPermissions,
} from "testHelpers/renderHelpers"
} from "testHelpers/entities"
import { server } from "testHelpers/server"
/**
@@ -6,19 +6,21 @@ import {
RuntimeErrorState,
} from "./RuntimeErrorState"
const renderComponent = () => {
// Given
const errorText = "broken!"
const errorStateProps = {
error: new Error(errorText),
}
// When
return render(<RuntimeErrorState {...errorStateProps} />)
}
describe("RuntimeErrorState", () => {
beforeEach(() => {
// Given
const errorText = "broken!"
const errorStateProps = {
error: new Error(errorText),
}
// When
render(<RuntimeErrorState {...errorStateProps} />)
})
it("should show stack when encountering runtime error", () => {
renderComponent()
// Then
const reportError = screen.getByText("broken!")
expect(reportError).toBeDefined()
@@ -29,6 +31,8 @@ describe("RuntimeErrorState", () => {
})
it("should have a button bar", () => {
renderComponent()
// Then
const copyCta = screen.getByText(ButtonLanguage.copyReport)
expect(copyCta).toBeDefined()
@@ -38,6 +42,8 @@ describe("RuntimeErrorState", () => {
})
it("should have an email link", () => {
renderComponent()
// Then
const emailLink = screen.getByText(RuntimeErrorStateLanguage.link)
expect(emailLink.closest("a")).toHaveAttribute(
@@ -1,8 +1,5 @@
import { Story } from "@storybook/react"
import {
MockWorkspace,
MockWorkspaceAgent,
} from "../../testHelpers/renderHelpers"
import { MockWorkspace, MockWorkspaceAgent } from "testHelpers/entities"
import { SSHButton, SSHButtonProps } from "./SSHButton"
export default {
@@ -1,6 +1,6 @@
import { Story } from "@storybook/react"
import { makeMockApiError } from "testHelpers/entities"
import { LoginErrors, SignInForm, SignInFormProps } from "./SignInForm"
import { SignInForm, SignInFormProps } from "./SignInForm"
export default {
title: "components/SignInForm",
@@ -17,17 +17,16 @@ const Template: Story<SignInFormProps> = (args: SignInFormProps) => (
export const SignedOut = Template.bind({})
SignedOut.args = {
isLoading: false,
loginErrors: {},
isSigningIn: false,
onSubmit: () => {
return Promise.resolve()
},
}
export const Loading = Template.bind({})
Loading.args = {
export const SigningIn = Template.bind({})
SigningIn.args = {
...SignedOut.args,
isLoading: true,
isSigningIn: true,
authMethods: {
password: { enabled: true },
github: { enabled: true },
@@ -35,67 +34,23 @@ Loading.args = {
},
}
export const WithLoginError = Template.bind({})
WithLoginError.args = {
export const WithError = Template.bind({})
WithError.args = {
...SignedOut.args,
loginErrors: {
[LoginErrors.AUTH_ERROR]: makeMockApiError({
message: "Email or password was invalid",
validations: [
{
field: "password",
detail: "Password is invalid.",
},
],
}),
},
error: makeMockApiError({
message: "Email or password was invalid",
validations: [
{
field: "password",
detail: "Password is invalid.",
},
],
}),
initialTouched: {
password: true,
},
}
export const WithGetUserError = Template.bind({})
WithGetUserError.args = {
...SignedOut.args,
loginErrors: {
[LoginErrors.GET_USER_ERROR]: makeMockApiError({
message: "You are logged out. Please log in to continue.",
detail: "API Key is invalid.",
}),
},
}
export const WithCheckPermissionsError = Template.bind({})
WithCheckPermissionsError.args = {
...SignedOut.args,
loginErrors: {
[LoginErrors.CHECK_PERMISSIONS_ERROR]: makeMockApiError({
message: "Unable to fetch user permissions",
detail: "Resource not found or you do not have access to this resource.",
}),
},
}
export const WithAuthMethodsError = Template.bind({})
WithAuthMethodsError.args = {
...SignedOut.args,
loginErrors: {
[LoginErrors.GET_METHODS_ERROR]: new Error("Failed to fetch auth methods"),
},
}
export const WithGetUserAndAuthMethodsError = Template.bind({})
WithGetUserAndAuthMethodsError.args = {
...SignedOut.args,
loginErrors: {
[LoginErrors.GET_USER_ERROR]: makeMockApiError({
message: "You are logged out. Please log in to continue.",
detail: "API Key is invalid.",
}),
[LoginErrors.GET_METHODS_ERROR]: new Error("Failed to fetch auth methods"),
},
}
export const WithGithub = Template.bind({})
WithGithub.args = {
...SignedOut.args,
@@ -1,5 +1,5 @@
import { Story } from "@storybook/react"
import * as Mocks from "../../testHelpers/renderHelpers"
import { MockTemplate, MockTemplateVersion } from "testHelpers/entities"
import {
TemplateStats,
TemplateStatsProps,
@@ -16,33 +16,33 @@ const Template: Story<TemplateStatsProps> = (args) => (
export const Example = Template.bind({})
Example.args = {
template: Mocks.MockTemplate,
activeVersion: Mocks.MockTemplateVersion,
template: MockTemplate,
activeVersion: MockTemplateVersion,
}
export const UsedByMany = Template.bind({})
UsedByMany.args = {
template: {
...Mocks.MockTemplate,
...MockTemplate,
active_user_count: 15,
},
activeVersion: Mocks.MockTemplateVersion,
activeVersion: MockTemplateVersion,
}
export const ActiveUsersNotLoaded = Template.bind({})
ActiveUsersNotLoaded.args = {
template: {
...Mocks.MockTemplate,
...MockTemplate,
active_user_count: -1,
},
activeVersion: Mocks.MockTemplateVersion,
activeVersion: MockTemplateVersion,
}
export const LongTemplateVersion = Template.bind({})
LongTemplateVersion.args = {
template: Mocks.MockTemplate,
template: MockTemplate,
activeVersion: {
...Mocks.MockTemplateVersion,
...MockTemplateVersion,
name: "thisisareallyreallylongnamefortesting",
},
}
@@ -52,8 +52,8 @@ LongTemplateVersion.parameters = {
export const SmallViewport = Template.bind({})
SmallViewport.args = {
template: Mocks.MockTemplate,
activeVersion: Mocks.MockTemplateVersion,
template: MockTemplate,
activeVersion: MockTemplateVersion,
}
SmallViewport.parameters = {
chromatic: { viewports: [600] },
@@ -1,5 +1,5 @@
import { Story } from "@storybook/react"
import { MockWorkspace } from "../../testHelpers/renderHelpers"
import { MockWorkspace } from "testHelpers/entities"
import { TerminalLink, TerminalLinkProps } from "./TerminalLink"
export default {
@@ -1,5 +1,5 @@
import { ComponentMeta, Story } from "@storybook/react"
import { MockUser, MockUserAgent } from "../../testHelpers/renderHelpers"
import { MockUser, MockUserAgent } from "testHelpers/entities"
import { UserCell, UserCellProps } from "./UserCell"
export default {
@@ -1,10 +1,7 @@
import { fireEvent, render, screen } from "@testing-library/react"
import { FC } from "react"
import {
MockUser,
MockUserAgent,
WrapperComponent,
} from "../../testHelpers/renderHelpers"
import { MockUser, MockUserAgent } from "testHelpers/entities"
import { WrapperComponent } from "../../testHelpers/renderHelpers"
import { UserCell, UserCellProps } from "./UserCell"
namespace Helpers {
@@ -1,9 +1,9 @@
import { ComponentMeta, Story } from "@storybook/react"
import {
MockAssignableSiteRoles,
MockUser,
MockUser2,
} from "../../testHelpers/renderHelpers"
MockAssignableSiteRoles,
} from "testHelpers/entities"
import { UsersTable, UsersTableProps } from "./UsersTable"
export default {
@@ -1,5 +1,5 @@
import { Story } from "@storybook/react"
import { MockWorkspace, MockWorkspaceAgent } from "testHelpers/renderHelpers"
import { MockWorkspace, MockWorkspaceAgent } from "testHelpers/entities"
import {
VSCodeDesktopButton,
VSCodeDesktopButtonProps,
@@ -1,10 +1,10 @@
import { ComponentMeta, Story } from "@storybook/react"
import dayjs from "dayjs"
import {
MockProvisionerJob,
MockStartingWorkspace,
MockWorkspaceBuild,
} from "../../testHelpers/renderHelpers"
MockProvisionerJob,
} from "testHelpers/entities"
import {
WorkspaceBuildProgress,
WorkspaceBuildProgressProps,
@@ -1,6 +1,5 @@
import { Story } from "@storybook/react"
import * as Mocks from "../../testHelpers/renderHelpers"
import { MockWorkspace } from "testHelpers/renderHelpers"
import { MockWorkspace } from "testHelpers/entities"
import {
WorkspaceStats,
WorkspaceStatsProps,
@@ -17,7 +16,7 @@ const Template: Story<WorkspaceStatsProps> = (args) => (
export const Example = Template.bind({})
Example.args = {
workspace: Mocks.MockWorkspace,
workspace: MockWorkspace,
}
export const Outdated = Template.bind({})
@@ -10,7 +10,7 @@ import {
MockStoppedWorkspace,
MockStoppingWorkspace,
MockWorkspace,
} from "testHelpers/renderHelpers"
} from "testHelpers/entities"
import {
WorkspaceStatusBadge,
WorkspaceStatusBadgeProps,
+1 -1
View File
@@ -10,7 +10,7 @@ describe("useCustomEvent", () => {
dispatchCustomEvent("testEvent", detail)
await waitFor(() => {
expect(callback).toBeCalledTimes(1)
expect(callback.mock.calls[0][0].detail).toBe(detail)
})
expect(callback.mock.calls[0][0].detail).toBe(detail)
})
})
+4 -2
View File
@@ -3,11 +3,13 @@ import userEvent from "@testing-library/user-event"
import * as API from "api/api"
import { rest } from "msw"
import {
renderWithAuth,
MockAuditLog,
MockAuditLog2,
waitForLoaderToBeRemoved,
MockEntitlementsWithAuditLog,
} from "testHelpers/entities"
import {
renderWithAuth,
waitForLoaderToBeRemoved,
} from "testHelpers/renderHelpers"
import { server } from "testHelpers/server"
@@ -1,22 +1,22 @@
import { renderWithAuth } from "testHelpers/renderHelpers"
import CreateTemplatePage from "./CreateTemplatePage"
import { screen, waitFor, within } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import * as API from "api/api"
import {
MockOrganization,
MockProvisionerJob,
MockTemplate,
MockTemplateExample,
MockTemplateVersion,
MockTemplateVersionVariable1,
MockTemplateVersionVariable2,
MockTemplateVersionVariable3,
renderWithAuth,
} from "testHelpers/renderHelpers"
import CreateTemplatePage from "./CreateTemplatePage"
import { screen, waitFor, within } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import * as API from "api/api"
MockTemplate,
MockOrganization,
MockProvisionerJob,
} from "testHelpers/entities"
const renderPage = async () => {
// Render with the example ID so we don't need to upload a file
const result = renderWithAuth(<CreateTemplatePage />, {
const view = renderWithAuth(<CreateTemplatePage />, {
route: `/templates/new?exampleId=${MockTemplateExample.id}`,
path: "/templates/new",
// We need this because after creation, the user will be redirected to here
@@ -25,7 +25,7 @@ const renderPage = async () => {
// It is lazy loaded, so we have to wait for it to be rendered to not get an
// act error
await screen.findByLabelText("Icon", undefined, { timeout: 5000 })
return result
return view
}
test("Create template with variables", async () => {
@@ -14,7 +14,10 @@ import {
MockTemplateVersionParameter3,
MockTemplateVersionGitAuth,
} from "testHelpers/entities"
import { renderWithAuth } from "testHelpers/renderHelpers"
import {
renderWithAuth,
waitForLoaderToBeRemoved,
} from "testHelpers/renderHelpers"
import CreateWorkspacePage from "./CreateWorkspacePage"
const { t } = i18next
@@ -147,15 +150,13 @@ describe("CreateWorkspacePage", () => {
.spyOn(API, "getTemplateVersionRichParameters")
.mockResolvedValueOnce([MockTemplateVersionParameter1])
await waitFor(() =>
renderWithAuth(<CreateWorkspacePage />, {
route:
"/templates/" +
MockTemplate.name +
`/workspace?param.${param}=${paramValue}`,
path: "/templates/:template/workspace",
}),
)
renderWithAuth(<CreateWorkspacePage />, {
route:
"/templates/" +
MockTemplate.name +
`/workspace?param.${param}=${paramValue}`,
path: "/templates/:template/workspace",
})
await screen.findByDisplayValue(paramValue)
})
@@ -168,7 +169,8 @@ describe("CreateWorkspacePage", () => {
MockTemplateVersionParameter2,
])
await waitFor(() => renderCreateWorkspacePage())
renderCreateWorkspacePage()
await waitForLoaderToBeRemoved()
const element = await screen.findByText("Create workspace")
expect(element).toBeDefined()
@@ -202,7 +204,8 @@ describe("CreateWorkspacePage", () => {
MockTemplateVersionParameter3,
])
await waitFor(() => renderCreateWorkspacePage())
renderCreateWorkspacePage()
await waitForLoaderToBeRemoved()
const element = await screen.findByText(createWorkspaceText)
expect(element).toBeDefined()
@@ -230,7 +233,8 @@ describe("CreateWorkspacePage", () => {
.spyOn(API, "getTemplateVersionGitAuth")
.mockResolvedValueOnce([MockTemplateVersionGitAuth])
await waitFor(() => renderCreateWorkspacePage())
renderCreateWorkspacePage()
await waitForLoaderToBeRemoved()
const nameField = await screen.findByLabelText(nameLabelText)
@@ -1,6 +1,6 @@
import { screen } from "@testing-library/react"
import { MockTemplateExample } from "testHelpers/entities"
import {
MockTemplateExample,
renderWithAuth,
waitForLoaderToBeRemoved,
} from "testHelpers/renderHelpers"
@@ -1,7 +1,6 @@
import { screen } from "@testing-library/react"
import { MockTemplateExample, MockTemplateExample2 } from "testHelpers/entities"
import {
MockTemplateExample,
MockTemplateExample2,
renderWithAuth,
waitForLoaderToBeRemoved,
} from "testHelpers/renderHelpers"
@@ -3,12 +3,12 @@ import { TemplateLayout } from "components/TemplateLayout/TemplateLayout"
import { rest } from "msw"
import { ResizeObserver } from "resize-observer"
import {
MockMemberPermissions,
MockTemplate,
MockTemplateVersion,
MockWorkspaceResource,
renderWithAuth,
} from "testHelpers/renderHelpers"
MockTemplateVersion,
MockMemberPermissions,
} from "testHelpers/entities"
import { renderWithAuth } from "testHelpers/renderHelpers"
import { server } from "testHelpers/server"
import * as CreateDayString from "util/createDayString"
import { TemplateSummaryPage } from "./TemplateSummaryPage"
@@ -1,5 +1,11 @@
import { Story } from "@storybook/react"
import * as Mocks from "testHelpers/renderHelpers"
import {
MockTemplate,
MockTemplateDAUResponse,
MockTemplateVersion,
MockWorkspaceResource,
MockWorkspaceResource2,
} from "testHelpers/entities"
import {
TemplateSummaryPageView,
TemplateSummaryPageViewProps,
@@ -16,31 +22,31 @@ const Template: Story<TemplateSummaryPageViewProps> = (args) => (
export const Example = Template.bind({})
Example.args = {
template: Mocks.MockTemplate,
activeVersion: Mocks.MockTemplateVersion,
template: MockTemplate,
activeVersion: MockTemplateVersion,
data: {
resources: [Mocks.MockWorkspaceResource, Mocks.MockWorkspaceResource2],
versions: [Mocks.MockTemplateVersion],
daus: Mocks.MockTemplateDAUResponse,
resources: [MockWorkspaceResource, MockWorkspaceResource2],
versions: [MockTemplateVersion],
daus: MockTemplateDAUResponse,
},
}
export const NoIcon = Template.bind({})
NoIcon.args = {
template: { ...Mocks.MockTemplate, icon: "" },
activeVersion: Mocks.MockTemplateVersion,
template: { ...MockTemplate, icon: "" },
activeVersion: MockTemplateVersion,
data: {
resources: [Mocks.MockWorkspaceResource, Mocks.MockWorkspaceResource2],
versions: [Mocks.MockTemplateVersion],
daus: Mocks.MockTemplateDAUResponse,
resources: [MockWorkspaceResource, MockWorkspaceResource2],
versions: [MockTemplateVersion],
daus: MockTemplateDAUResponse,
},
}
export const SmallViewport = Template.bind({})
SmallViewport.args = {
template: Mocks.MockTemplate,
template: MockTemplate,
activeVersion: {
...Mocks.MockTemplateVersion,
...MockTemplateVersion,
readme: `---
name:Template test
---
@@ -54,9 +60,9 @@ SmallViewport.args = {
`,
},
data: {
resources: [Mocks.MockWorkspaceResource, Mocks.MockWorkspaceResource2],
versions: [Mocks.MockTemplateVersion],
daus: Mocks.MockTemplateDAUResponse,
resources: [MockWorkspaceResource, MockWorkspaceResource2],
versions: [MockTemplateVersion],
daus: MockTemplateDAUResponse,
},
}
SmallViewport.parameters = {
@@ -1,7 +1,6 @@
import { action } from "@storybook/addon-actions"
import { Story } from "@storybook/react"
import * as Mocks from "../../../testHelpers/renderHelpers"
import { makeMockApiError } from "../../../testHelpers/renderHelpers"
import { makeMockApiError, MockTemplate } from "testHelpers/entities"
import {
TemplateSettingsPageView,
TemplateSettingsPageViewProps,
@@ -11,7 +10,7 @@ export default {
title: "pages/TemplateSettingsPageView",
component: TemplateSettingsPageView,
args: {
template: Mocks.MockTemplate,
template: MockTemplate,
onSubmit: action("onSubmit"),
onCancel: action("cancel"),
},
@@ -1,6 +1,6 @@
import { action } from "@storybook/addon-actions"
import { Story } from "@storybook/react"
import * as Mocks from "../../../testHelpers/renderHelpers"
import { MockTemplate } from "testHelpers/entities"
import {
TemplateSchedulePageView,
TemplateSchedulePageViewProps,
@@ -11,7 +11,7 @@ export default {
component: TemplateSchedulePageView,
args: {
canSetMaxTTL: true,
template: Mocks.MockTemplate,
template: MockTemplate,
onSubmit: action("onSubmit"),
onCancel: action("cancel"),
},
@@ -1,12 +1,6 @@
import { screen } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import {
MockTemplate,
MockTemplateVersion2,
MockTemplateVersion,
MockTemplateVersionVariable1,
MockTemplateVersionVariable2,
MockTemplateVersionVariable5,
renderWithTemplateSettingsLayout,
waitForLoaderToBeRemoved,
} from "testHelpers/renderHelpers"
@@ -14,6 +8,14 @@ import * as API from "api/api"
import i18next from "i18next"
import TemplateVariablesPage from "./TemplateVariablesPage"
import { Language as FooterFormLanguage } from "components/FormFooter/FormFooter"
import {
MockTemplate,
MockTemplateVersion,
MockTemplateVersionVariable1,
MockTemplateVersionVariable2,
MockTemplateVersion2,
MockTemplateVersionVariable5,
} from "testHelpers/entities"
const { t } = i18next
@@ -1,12 +1,12 @@
import {
MockTemplateVersion,
MockWorkspaceBuildLogs,
renderWithAuth,
} from "testHelpers/renderHelpers"
import { renderWithAuth } from "testHelpers/renderHelpers"
import TemplateVersionEditorPage from "./TemplateVersionEditorPage"
import { screen, waitFor, within } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import * as api from "api/api"
import {
MockTemplateVersion,
MockWorkspaceBuildLogs,
} from "testHelpers/entities"
// For some reason this component in Jest is throwing a MUI style warning so,
// since we don't need it for this test, we can mock it out
@@ -71,9 +71,9 @@ test("Use custom name and set it as active when publishing", async () => {
expect(patchTemplateVersion).toBeCalledWith("new-version-id", {
name: "v1.0",
})
expect(updateActiveTemplateVersion).toBeCalledWith("test-template", {
id: "new-version-id",
})
})
expect(updateActiveTemplateVersion).toBeCalledWith("test-template", {
id: "new-version-id",
})
})
@@ -36,7 +36,7 @@ describe("TemplateVersionPage", () => {
beforeEach(setup)
it("shows files", () => {
expect(screen.queryByText(TERRAFORM_FILENAME)).toBeInTheDocument()
expect(screen.queryByText(README_FILENAME)).toBeInTheDocument()
expect(screen.getByText(TERRAFORM_FILENAME)).toBeInTheDocument()
expect(screen.getByText(README_FILENAME)).toBeInTheDocument()
})
})
@@ -3,14 +3,10 @@ import "jest-canvas-mock"
import WS from "jest-websocket-mock"
import { rest } from "msw"
import { Route, Routes } from "react-router-dom"
import { MockWorkspace, MockWorkspaceAgent } from "testHelpers/entities"
import { TextDecoder, TextEncoder } from "util"
import { ReconnectingPTYRequest } from "../../api/types"
import {
history,
MockWorkspace,
MockWorkspaceAgent,
render,
} from "../../testHelpers/renderHelpers"
import { history, render } from "../../testHelpers/renderHelpers"
import { server } from "../../testHelpers/server"
import TerminalPage, { Language } from "./TerminalPage"
@@ -1,12 +1,10 @@
import { fireEvent, screen, within } from "@testing-library/react"
import * as API from "../../../api/api"
import {
MockGitSSHKey,
renderWithAuth,
} from "../../../testHelpers/renderHelpers"
import { renderWithAuth } from "../../../testHelpers/renderHelpers"
import { Language as SSHKeysPageLanguage, SSHKeysPage } from "./SSHKeysPage"
import { Language as SSHKeysPageViewLanguage } from "./SSHKeysPageView"
import { i18n } from "i18n"
import { MockGitSSHKey } from "testHelpers/entities"
const { t } = i18n
@@ -90,7 +90,7 @@ describe("Create User Page", () => {
it("shows success notification and redirects to users page", async () => {
await renderCreateUserPage()
await fillForm({})
const successMessage = screen.findByText(
const successMessage = await screen.findByText(
CreateUserLanguage.createUserSuccess,
)
expect(successMessage).toBeDefined()
+9 -9
View File
@@ -2,18 +2,18 @@ import { fireEvent, screen, waitFor, within } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import { i18n } from "i18n"
import { rest } from "msw"
import {
MockUser,
MockUser2,
SuspendedMockUser,
MockAuditorRole,
MockOwnerRole,
} from "testHelpers/entities"
import { Language as usersXServiceLanguage } from "xServices/users/usersXService"
import * as API from "../../api/api"
import { Role } from "../../api/typesGenerated"
import { Language as ResetPasswordDialogLanguage } from "../../components/Dialogs/ResetPasswordDialog/ResetPasswordDialog"
import {
MockAuditorRole,
MockOwnerRole,
MockUser,
MockUser2,
renderWithAuth,
SuspendedMockUser,
} from "../../testHelpers/renderHelpers"
import { renderWithAuth } from "../../testHelpers/renderHelpers"
import { server } from "../../testHelpers/server"
import { Language as UsersPageLanguage, UsersPage } from "./UsersPage"
@@ -401,8 +401,8 @@ describe("UsersPage", () => {
// Check if the select text was updated with the Auditor role
await waitFor(() => {
expect(userRow).toHaveTextContent(MockOwnerRole.display_name)
expect(userRow).toHaveTextContent(MockAuditorRole.display_name)
})
expect(userRow).toHaveTextContent(MockAuditorRole.display_name)
// Check if the API was called correctly
const currentRoles = MockUser.roles.map((r) => r.name)
@@ -1,10 +1,10 @@
import { ComponentMeta, Story } from "@storybook/react"
import { createPaginationRef } from "components/PaginationWidget/utils"
import {
MockAssignableSiteRoles,
MockUser,
MockUser2,
} from "../../testHelpers/renderHelpers"
MockAssignableSiteRoles,
} from "testHelpers/entities"
import { UsersPageView, UsersPageViewProps } from "./UsersPageView"
export default {
@@ -3,24 +3,26 @@ import userEvent from "@testing-library/user-event"
import EventSourceMock from "eventsourcemock"
import i18next from "i18next"
import { rest } from "msw"
import {
MockTemplate,
MockWorkspace,
MockWorkspaceBuild,
MockStoppedWorkspace,
MockStartingWorkspace,
MockOutdatedWorkspace,
MockTemplateVersionParameter1,
MockTemplateVersionParameter2,
MockStoppingWorkspace,
MockFailedWorkspace,
MockCancelingWorkspace,
MockCanceledWorkspace,
MockDeletingWorkspace,
MockDeletedWorkspace,
MockBuilds,
} from "testHelpers/entities"
import * as api from "../../api/api"
import { Workspace } from "../../api/typesGenerated"
import {
MockBuilds,
MockCanceledWorkspace,
MockCancelingWorkspace,
MockDeletedWorkspace,
MockDeletingWorkspace,
MockFailedWorkspace,
MockOutdatedWorkspace,
MockStartingWorkspace,
MockStoppedWorkspace,
MockStoppingWorkspace,
MockTemplate,
MockTemplateVersionParameter1,
MockTemplateVersionParameter2,
MockWorkspace,
MockWorkspaceBuild,
renderWithAuth,
waitForLoaderToBeRemoved,
} from "../../testHelpers/renderHelpers"
@@ -1,8 +1,4 @@
import {
MockUser,
MockWorkspace,
renderWithAuth,
} from "testHelpers/renderHelpers"
import { renderWithAuth } from "testHelpers/renderHelpers"
import userEvent from "@testing-library/user-event"
import { screen } from "@testing-library/react"
import {
@@ -23,6 +19,7 @@ import { WorkspaceSchedulePage } from "./WorkspaceSchedulePage"
import i18next from "i18next"
import { server } from "testHelpers/server"
import { rest } from "msw"
import { MockUser, MockWorkspace } from "testHelpers/entities"
const { t } = i18next
@@ -1,17 +1,19 @@
import userEvent from "@testing-library/user-event"
import {
MockTemplateVersionParameter1,
MockTemplateVersionParameter2,
MockWorkspace,
MockWorkspaceBuild,
MockWorkspaceBuildParameter1,
MockWorkspaceBuildParameter2,
renderWithAuth,
waitForLoaderToBeRemoved,
} from "testHelpers/renderHelpers"
import WorkspaceSettingsPage from "./WorkspaceSettingsPage"
import { screen, waitFor, within } from "@testing-library/react"
import * as api from "api/api"
import {
MockWorkspace,
MockTemplateVersionParameter1,
MockTemplateVersionParameter2,
MockWorkspaceBuildParameter1,
MockWorkspaceBuildParameter2,
MockWorkspaceBuild,
} from "testHelpers/entities"
test("Submit the workspace settings page successfully", async () => {
// Mock the API calls that loads data
@@ -69,12 +71,12 @@ test("Submit the workspace settings page successfully", async () => {
expect(patchWorkspaceSpy).toHaveBeenCalledWith(MockWorkspace.id, {
name: "new-name",
})
expect(postWorkspaceBuildSpy).toHaveBeenCalledWith(MockWorkspace.id, {
transition: "start",
rich_parameter_values: [
{ name: MockTemplateVersionParameter1.name, value: "new-value" },
{ name: MockTemplateVersionParameter2.name, value: "1" },
],
})
})
expect(postWorkspaceBuildSpy).toHaveBeenCalledWith(MockWorkspace.id, {
transition: "start",
rich_parameter_values: [
{ name: MockTemplateVersionParameter1.name, value: "new-value" },
{ name: MockTemplateVersionParameter2.name, value: "1" },
],
})
})
+6 -3
View File
@@ -132,6 +132,9 @@ export function renderWithTemplateSettingsLayout(
}
export const waitForLoaderToBeRemoved = (): Promise<void> =>
waitForElementToBeRemoved(() => screen.getByTestId("loader"))
export * from "./entities"
// Sometimes, we have pages that are doing a lot of requests to get done, so the
// default timeout of 1_000 is not enough. We should revisit this when we unify
// some of the endpoints
waitForElementToBeRemoved(() => screen.queryByTestId("loader"), {
timeout: 5_000,
})
@@ -132,7 +132,7 @@ describe("updateCheckMachine", () => {
updateCheckService.send("DISMISS")
await waitFor(() => {
expect(updateCheckService.state.matches("dismissed")).toBeTruthy()
expect(getDismissedVersionOnLocal()).toEqual(MockUpdateCheck.version)
})
expect(getDismissedVersionOnLocal()).toEqual(MockUpdateCheck.version)
})
})
+86 -36
View File
@@ -2,6 +2,11 @@
# yarn lockfile v1
"@adobe/css-tools@^4.0.1":
version "4.2.0"
resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.2.0.tgz#e1a84fca468f4b337816fcb7f0964beb620ba855"
integrity sha512-E09FiIft46CmH5Qnjb0wsW54/YQd69LsxeKUOWawmws1XWvyFGURnAChH0mlr7YPFR1ofwvUQfcL0J3lMxXqPA==
"@ampproject/remapping@^2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d"
@@ -1208,6 +1213,13 @@
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz#128b76ecb9be48b60cf5cfc1c63a4f00691a3239"
integrity sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==
"@eslint-community/eslint-utils@^4.2.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
dependencies:
eslint-visitor-keys "^3.3.0"
"@eslint/eslintrc@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.0.tgz#943309d8697c52fc82c076e90c1c74fbbe69dbff"
@@ -2986,10 +2998,10 @@
"@tanstack/query-core" "4.22.4"
use-sync-external-store "^1.2.0"
"@testing-library/dom@^8.5.0":
version "8.20.0"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.20.0.tgz#914aa862cef0f5e89b98cc48e3445c4c921010f6"
integrity sha512-d9ULIT+a4EXLX3UU8FBjauG9NnsZHkHztXoIcTsOKoOw030fyjheN9svkTULjJxtYag9DZz5Jz5qkWZDPxTFwA==
"@testing-library/dom@^9.0.0":
version "9.2.0"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-9.2.0.tgz#0e1f45e956f2a16f471559c06edd8827c4832f04"
integrity sha512-xTEnpUKiV/bMyEsE5bT4oYA0x0Z/colMtxzUY8bKyPXBNLn/e0V4ZjBZkEhms0xE4pv9QsPfSRu9AWS4y5wGvA==
dependencies:
"@babel/code-frame" "^7.10.4"
"@babel/runtime" "^7.12.5"
@@ -2997,19 +3009,19 @@
aria-query "^5.0.0"
chalk "^4.1.0"
dom-accessibility-api "^0.5.9"
lz-string "^1.4.4"
lz-string "^1.5.0"
pretty-format "^27.0.2"
"@testing-library/jest-dom@5.16.4":
version "5.16.4"
resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz#938302d7b8b483963a3ae821f1c0808f872245cd"
integrity sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA==
"@testing-library/jest-dom@5.16.5":
version "5.16.5"
resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz#3912846af19a29b2dbf32a6ae9c31ef52580074e"
integrity sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==
dependencies:
"@adobe/css-tools" "^4.0.1"
"@babel/runtime" "^7.9.2"
"@types/testing-library__jest-dom" "^5.9.1"
aria-query "^5.0.0"
chalk "^3.0.0"
css "^3.0.0"
css.escape "^1.5.1"
dom-accessibility-api "^0.5.6"
lodash "^4.17.15"
@@ -3023,13 +3035,13 @@
"@babel/runtime" "^7.12.5"
react-error-boundary "^3.1.0"
"@testing-library/react@13.4.0":
version "13.4.0"
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-13.4.0.tgz#6a31e3bf5951615593ad984e96b9e5e2d9380966"
integrity sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==
"@testing-library/react@14.0.0":
version "14.0.0"
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-14.0.0.tgz#59030392a6792450b9ab8e67aea5f3cc18d6347c"
integrity sha512-S04gSNJbYE30TlIMLTzv6QCTzt9AqIF5y6s6SzVFILNcNvbV/jU96GeiTPillGQo+Ny64M/5PV7klNYYgv5Dfg==
dependencies:
"@babel/runtime" "^7.12.5"
"@testing-library/dom" "^8.5.0"
"@testing-library/dom" "^9.0.0"
"@types/react-dom" "^18.0.0"
"@testing-library/user-event@14.4.3":
@@ -3622,6 +3634,14 @@
"@typescript-eslint/types" "5.53.0"
"@typescript-eslint/visitor-keys" "5.53.0"
"@typescript-eslint/scope-manager@5.57.0":
version "5.57.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.57.0.tgz#79ccd3fa7bde0758059172d44239e871e087ea36"
integrity sha512-NANBNOQvllPlizl9LatX8+MHi7bx7WGIWYjPHDmQe5Si/0YEYfxSljJpoTyTWFTgRy3X8gLYSE4xQ2U+aCozSw==
dependencies:
"@typescript-eslint/types" "5.57.0"
"@typescript-eslint/visitor-keys" "5.57.0"
"@typescript-eslint/type-utils@5.50.0":
version "5.50.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.50.0.tgz#509d5cc9728d520008f7157b116a42c5460e7341"
@@ -3647,6 +3667,11 @@
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.53.0.tgz#f79eca62b97e518ee124086a21a24f3be267026f"
integrity sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A==
"@typescript-eslint/types@5.57.0":
version "5.57.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.57.0.tgz#727bfa2b64c73a4376264379cf1f447998eaa132"
integrity sha512-mxsod+aZRSyLT+jiqHw1KK6xrANm19/+VFALVFP5qa/aiJnlP38qpyaTd0fEKhWvQk6YeNZ5LGwI1pDpBRBhtQ==
"@typescript-eslint/typescript-estree@5.45.1":
version "5.45.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.1.tgz#b3dc37f0c4f0fe73e09917fc735e6f96eabf9ba4"
@@ -3686,6 +3711,19 @@
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/typescript-estree@5.57.0":
version "5.57.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.57.0.tgz#ebcd0ee3e1d6230e888d88cddf654252d41e2e40"
integrity sha512-LTzQ23TV82KpO8HPnWuxM2V7ieXW8O142I7hQTxWIHDcCEIjtkat6H96PFkYBQqGFLW/G/eVVOB9Z8rcvdY/Vw==
dependencies:
"@typescript-eslint/types" "5.57.0"
"@typescript-eslint/visitor-keys" "5.57.0"
debug "^4.3.4"
globby "^11.1.0"
is-glob "^4.0.3"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/utils@5.50.0":
version "5.50.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.50.0.tgz#807105f5ffb860644d30d201eefad7017b020816"
@@ -3714,6 +3752,20 @@
eslint-utils "^3.0.0"
semver "^7.3.7"
"@typescript-eslint/utils@^5.43.0":
version "5.57.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.57.0.tgz#eab8f6563a2ac31f60f3e7024b91bf75f43ecef6"
integrity sha512-ps/4WohXV7C+LTSgAL5CApxvxbMkl9B9AUZRtnEFonpIxZDIT7wC1xfvuJONMidrkB9scs4zhtRyIwHh4+18kw==
dependencies:
"@eslint-community/eslint-utils" "^4.2.0"
"@types/json-schema" "^7.0.9"
"@types/semver" "^7.3.12"
"@typescript-eslint/scope-manager" "5.57.0"
"@typescript-eslint/types" "5.57.0"
"@typescript-eslint/typescript-estree" "5.57.0"
eslint-scope "^5.1.1"
semver "^7.3.7"
"@typescript-eslint/visitor-keys@5.45.1":
version "5.45.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.1.tgz#204428430ad6a830d24c5ac87c71366a1cfe1948"
@@ -3738,6 +3790,14 @@
"@typescript-eslint/types" "5.53.0"
eslint-visitor-keys "^3.3.0"
"@typescript-eslint/visitor-keys@5.57.0":
version "5.57.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.57.0.tgz#e2b2f4174aff1d15eef887ce3d019ecc2d7a8ac1"
integrity sha512-ery2g3k0hv5BLiKpPuwYt9KBkAp2ugT6VvyShXdLOkax895EC55sP0Tx5L0fZaQueiK3fBLvHVvEl3jFS5ia+g==
dependencies:
"@typescript-eslint/types" "5.57.0"
eslint-visitor-keys "^3.3.0"
"@vitejs/plugin-react@2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-2.1.0.tgz#4c99df15e71d2630601bd3018093bdc787d40e55"
@@ -5956,15 +6016,6 @@ css.escape@^1.5.1:
resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb"
integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==
css@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d"
integrity sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==
dependencies:
inherits "^2.0.4"
source-map "^0.6.1"
source-map-resolve "^0.6.0"
cssesc@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
@@ -6944,6 +6995,13 @@ eslint-plugin-react@7.31.1:
semver "^6.3.0"
string.prototype.matchall "^4.0.7"
eslint-plugin-testing-library@^5.10.2:
version "5.10.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.10.2.tgz#12f231ad9b52b6aef45c801fd00aa129a932e0c2"
integrity sha512-f1DmDWcz5SDM+IpCkEX0lbFqrrTs8HRsEElzDEqN/EBI0hpRj8Cns5+IVANXswE8/LeybIJqPAOQIFu2j5Y5sw==
dependencies:
"@typescript-eslint/utils" "^5.43.0"
eslint-plugin-unicorn@44.0.0:
version "44.0.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-44.0.0.tgz#ddb2d7bf3674077d6f3b227b9a0ce22dfc1e3ceb"
@@ -10180,10 +10238,10 @@ luxon@^3.1.0:
resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.2.1.tgz#14f1af209188ad61212578ea7e3d518d18cee45f"
integrity sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg==
lz-string@^1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"
integrity sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==
lz-string@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941"
integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==
magic-string@^0.26.2:
version "0.26.7"
@@ -13413,14 +13471,6 @@ source-map-resolve@^0.5.0:
source-map-url "^0.4.0"
urix "^0.1.0"
source-map-resolve@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2"
integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==
dependencies:
atob "^2.1.2"
decode-uri-component "^0.2.0"
source-map-support@0.5.13:
version "0.5.13"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932"