diff --git a/packages/manager/.changeset/pr-11085-tests-1728657019139.md b/packages/manager/.changeset/pr-11085-tests-1728657019139.md deleted file mode 100644 index 882e40644d2..00000000000 --- a/packages/manager/.changeset/pr-11085-tests-1728657019139.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tests ---- - -Use `happy-dom` instead of `jsdom` in unit tests ([#11085](https://github.com/linode/manager/pull/11085)) diff --git a/packages/manager/package.json b/packages/manager/package.json index 10248b48034..41241a56de8 100644 --- a/packages/manager/package.json +++ b/packages/manager/package.json @@ -195,7 +195,7 @@ "eslint-plugin-xss": "^0.1.10", "factory.ts": "^0.5.1", "glob": "^10.3.1", - "happy-dom": "^15.7.4", + "jsdom": "^24.1.1", "junit2json": "^3.1.4", "lint-staged": "^15.2.9", "mocha-junit-reporter": "^2.2.1", diff --git a/packages/manager/src/components/Avatar/Avatar.test.tsx b/packages/manager/src/components/Avatar/Avatar.test.tsx index e8f7ae51d3a..65e4ab1baa0 100644 --- a/packages/manager/src/components/Avatar/Avatar.test.tsx +++ b/packages/manager/src/components/Avatar/Avatar.test.tsx @@ -31,7 +31,7 @@ describe('Avatar', () => { const avatarStyles = getComputedStyle(avatar); expect(getByTestId('avatar-letter')).toHaveTextContent('M'); - expect(avatarStyles.backgroundColor).toBe('#0174bc'); // theme.color.primary.dark (#0174bc) + expect(avatarStyles.backgroundColor).toBe('rgb(1, 116, 188)'); // theme.color.primary.dark (#0174bc) }); it('should render a background color from props', () => { @@ -48,8 +48,8 @@ describe('Avatar', () => { const avatarTextStyles = getComputedStyle(avatarText); // Confirm background color contrasts with text color. - expect(avatarStyles.backgroundColor).toBe('#000000'); // black - expect(avatarTextStyles.color).toBe('#fff'); // white + expect(avatarStyles.backgroundColor).toBe('rgb(0, 0, 0)'); // black + expect(avatarTextStyles.color).toBe('rgb(255, 255, 255)'); // white }); it('should render the first letter of username from props', async () => { diff --git a/packages/manager/src/components/BetaChip/BetaChip.test.tsx b/packages/manager/src/components/BetaChip/BetaChip.test.tsx index 69d7d499fe2..39d28178640 100644 --- a/packages/manager/src/components/BetaChip/BetaChip.test.tsx +++ b/packages/manager/src/components/BetaChip/BetaChip.test.tsx @@ -17,7 +17,7 @@ describe('BetaChip', () => { const { getByTestId } = renderWithTheme(); const betaChip = getByTestId('betaChip'); expect(betaChip).toBeInTheDocument(); - expect(betaChip).toHaveStyle('background-color: #108ad6'); + expect(betaChip).toHaveStyle('background-color: rgb(16, 138, 214)'); }); it('triggers an onClick callback', () => { diff --git a/packages/manager/src/components/DescriptionList/DescriptionList.test.tsx b/packages/manager/src/components/DescriptionList/DescriptionList.test.tsx index 477d27088f0..6fc2fd2fe20 100644 --- a/packages/manager/src/components/DescriptionList/DescriptionList.test.tsx +++ b/packages/manager/src/components/DescriptionList/DescriptionList.test.tsx @@ -32,7 +32,7 @@ describe('Description List', () => { it('has it title bolded', () => { const { getByText } = renderWithTheme(); const title = getByText('Random title'); - expect(title).toHaveStyle('font-family: LatoWebBold, sans-serif'); + expect(title).toHaveStyle('font-family: "LatoWebBold",sans-serif'); }); it('renders a column by default', () => { diff --git a/packages/manager/src/components/HighlightedMarkdown/__snapshots__/HighlightedMarkdown.test.tsx.snap b/packages/manager/src/components/HighlightedMarkdown/__snapshots__/HighlightedMarkdown.test.tsx.snap index 09a0177c34b..238b90d44c9 100644 --- a/packages/manager/src/components/HighlightedMarkdown/__snapshots__/HighlightedMarkdown.test.tsx.snap +++ b/packages/manager/src/components/HighlightedMarkdown/__snapshots__/HighlightedMarkdown.test.tsx.snap @@ -4,52 +4,52 @@ exports[`HighlightedMarkdown component > should highlight text consistently 1`]

-

- Some markdown -

- + /> +

+ Some markdown +

+ -
-      
+    
+      
+        const
+      
+       x = 
+      
         
-          const
-        
-         x = 
-        
-          
-            function
-          
-          (
-          
-          ) 
-        
-        { 
-        
-          return
+          function
         
-         
+        (
         
-          true
-        
-        ; }
+          class="hljs-params"
+        />
+        ) 
+      
+      { 
+      
+        return
+      
+       
+      
+        true
+      
+      ; }
 
-      
-    
-

+
+ +

`; diff --git a/packages/manager/src/components/Notice/Notice.test.tsx b/packages/manager/src/components/Notice/Notice.test.tsx index 029e9d86d10..e7d536cd907 100644 --- a/packages/manager/src/components/Notice/Notice.test.tsx +++ b/packages/manager/src/components/Notice/Notice.test.tsx @@ -11,8 +11,8 @@ describe('Notice Component', () => { const notice = container.firstChild; expect(notice).toHaveStyle('margin-bottom: 24px'); - expect(notice).toHaveStyle('margin-left: 0px'); - expect(notice).toHaveStyle('margin-top: 0px'); + expect(notice).toHaveStyle('margin-left: 0'); + expect(notice).toHaveStyle('margin-top: 0'); }); it('renders with text', () => { diff --git a/packages/manager/src/components/Tabs/Tab.test.tsx b/packages/manager/src/components/Tabs/Tab.test.tsx index 4dc53cd77da..6463053b864 100644 --- a/packages/manager/src/components/Tabs/Tab.test.tsx +++ b/packages/manager/src/components/Tabs/Tab.test.tsx @@ -20,7 +20,7 @@ describe('Tab Component', () => { expect(tabElement).toHaveStyle(` display: inline-flex; - color: #0174bc; + color: rgb(0, 156, 222); `); }); diff --git a/packages/manager/src/components/TextTooltip/TextTooltip.test.tsx b/packages/manager/src/components/TextTooltip/TextTooltip.test.tsx index ba592caabed..301c5787ca5 100644 --- a/packages/manager/src/components/TextTooltip/TextTooltip.test.tsx +++ b/packages/manager/src/components/TextTooltip/TextTooltip.test.tsx @@ -56,7 +56,7 @@ describe('TextTooltip', () => { const displayText = getByText(props.displayText); - expect(displayText).toHaveStyle('color: #0174bc'); + expect(displayText).toHaveStyle('color: rgb(0, 156, 222)'); expect(displayText).toHaveStyle('font-size: 18px'); }); diff --git a/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.test.tsx b/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.test.tsx index eee0966bf78..40b0bf1c6ce 100644 --- a/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.test.tsx +++ b/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.test.tsx @@ -24,9 +24,7 @@ describe('Database Create', () => { const { getAllByTestId, getAllByText } = renderWithTheme( ); - await waitForElementToBeRemoved(getAllByTestId(loadingTestId), { - timeout: 10_000, - }); + await waitForElementToBeRemoved(getAllByTestId(loadingTestId)); getAllByText('Cluster Label'); getAllByText('Database Engine'); diff --git a/packages/manager/src/features/Databases/DatabaseLanding/DatabaseLanding.test.tsx b/packages/manager/src/features/Databases/DatabaseLanding/DatabaseLanding.test.tsx index d4c3f11d44d..a7230c71e9f 100644 --- a/packages/manager/src/features/Databases/DatabaseLanding/DatabaseLanding.test.tsx +++ b/packages/manager/src/features/Databases/DatabaseLanding/DatabaseLanding.test.tsx @@ -1,4 +1,4 @@ -import { screen, waitFor, within } from '@testing-library/react'; +import { screen, within } from '@testing-library/react'; import { fireEvent } from '@testing-library/react'; import { waitForElementToBeRemoved } from '@testing-library/react'; import { DateTime } from 'luxon'; @@ -71,7 +71,6 @@ describe('Database Table Row', () => { describe('Database Table', () => { it('should render database landing table with items', async () => { - const database = databaseInstanceFactory.build({ status: 'active' }); const mockAccount = accountFactory.build({ capabilities: [managedDBBetaCapability], }); @@ -82,25 +81,32 @@ describe('Database Table', () => { ); server.use( http.get(databaseInstancesEndpoint, () => { - return HttpResponse.json(makeResourcePage([database])); + const databases = databaseInstanceFactory.buildList(1, { + status: 'active', + }); + return HttpResponse.json(makeResourcePage(databases)); }) ); - const { getByText } = renderWithTheme(); + const { getAllByText, getByTestId, queryAllByText } = renderWithTheme( + + ); - // wait for API data to load - await waitFor(() => expect(getByText(database.label)).toBeVisible(), { - timeout: 10_000, - }); - expect(getByText('Active')).toBeVisible(); + // Loading state should render + expect(getByTestId(loadingTestId)).toBeInTheDocument(); + + await waitForElementToBeRemoved(getByTestId(loadingTestId)); // Static text and table column headers - expect(getByText('Cluster Label')).toBeVisible(); - expect(getByText('Status')).toBeVisible(); - expect(getByText('Configuration')).toBeVisible(); - expect(getByText('Engine')).toBeVisible(); - expect(getByText('Region')).toBeVisible(); - expect(getByText('Created')).toBeVisible(); + getAllByText('Cluster Label'); + getAllByText('Status'); + getAllByText('Configuration'); + getAllByText('Engine'); + getAllByText('Region'); + getAllByText('Created'); + + // Check to see if the mocked API data rendered in the table + queryAllByText('Active'); }); it('should render database landing with empty state', async () => { diff --git a/packages/manager/src/features/Kubernetes/CreateCluster/HAControlPlane.test.tsx b/packages/manager/src/features/Kubernetes/CreateCluster/HAControlPlane.test.tsx index 94968d34b79..b8f995c02f1 100644 --- a/packages/manager/src/features/Kubernetes/CreateCluster/HAControlPlane.test.tsx +++ b/packages/manager/src/features/Kubernetes/CreateCluster/HAControlPlane.test.tsx @@ -1,4 +1,4 @@ -import userEvent from '@testing-library/user-event'; +import { fireEvent } from '@testing-library/react'; import * as React from 'react'; import { UNKNOWN_PRICE } from 'src/utilities/pricing/constants'; @@ -42,11 +42,11 @@ describe('HAControlPlane', () => { await findByText(/\$60\.00/); }); - it('should call the handleChange function on change', async () => { + it('should call the handleChange function on change', () => { const { getByTestId } = renderWithTheme(); const haRadioButton = getByTestId('ha-radio-button-yes'); - await userEvent.click(haRadioButton); + fireEvent.click(haRadioButton); expect(props.setHighAvailability).toHaveBeenCalled(); }); }); diff --git a/packages/manager/src/features/Linodes/CloneLanding/Disks.test.tsx b/packages/manager/src/features/Linodes/CloneLanding/Disks.test.tsx index 396cc774603..dc55a90af9e 100644 --- a/packages/manager/src/features/Linodes/CloneLanding/Disks.test.tsx +++ b/packages/manager/src/features/Linodes/CloneLanding/Disks.test.tsx @@ -33,7 +33,7 @@ describe('Disks', () => { const { getByTestId } = render(wrapWithTheme()); disks.forEach((eachDisk) => { const checkbox = getByTestId(`checkbox-${eachDisk.id}`).parentNode; - fireEvent.click(checkbox!); + fireEvent.click(checkbox as any); expect(mockHandleSelect).toHaveBeenCalledWith(eachDisk.id); }); }); @@ -47,10 +47,10 @@ describe('Disks', () => { }); it('checks the disk if the associated config is selected', () => { - const { getByRole } = render( + const { getByTestId } = render( wrapWithTheme() ); - const checkbox = getByRole('checkbox', { name: '512 MB Swap Image' }); - expect(checkbox).toBeChecked(); + const checkbox: any = getByTestId('checkbox-19040624').firstElementChild; + expect(checkbox).toHaveAttribute('checked'); }); }); diff --git a/packages/manager/src/features/Linodes/LinodeCreate/VPC/VPC.test.tsx b/packages/manager/src/features/Linodes/LinodeCreate/VPC/VPC.test.tsx index a500440cfb3..eb193d24815 100644 --- a/packages/manager/src/features/Linodes/LinodeCreate/VPC/VPC.test.tsx +++ b/packages/manager/src/features/Linodes/LinodeCreate/VPC/VPC.test.tsx @@ -69,7 +69,7 @@ describe('VPC', () => { it('renders VPC IPv4, NAT checkboxes, and IP Ranges inputs when a subnet is selected', async () => { const { - getByRole, + getByLabelText, getByText, } = renderWithThemeAndHookFormContext({ component: , @@ -82,15 +82,13 @@ describe('VPC', () => { }); expect( - getByRole('checkbox', { - name: 'Auto-assign a VPC IPv4 address for this Linode in the VPC', - }) + getByLabelText( + 'Auto-assign a VPC IPv4 address for this Linode in the VPC' + ) ).toBeInTheDocument(); expect( - getByRole('checkbox', { - name: 'Assign a public IPv4 address for this Linode', - }) + getByLabelText('Assign a public IPv4 address for this Linode') ).toBeInTheDocument(); expect(getByText('Assign additional IPv4 ranges')).toBeInTheDocument(); @@ -98,7 +96,7 @@ describe('VPC', () => { it('should check the VPC IPv4 if a "ipv4.vpc" is null/undefined', async () => { const { - getByRole, + getByLabelText, } = renderWithThemeAndHookFormContext({ component: , useFormOptions: { @@ -114,16 +112,15 @@ describe('VPC', () => { }); expect( - getByRole('checkbox', { - name: 'Auto-assign a VPC IPv4 address for this Linode in the VPC', - }) + getByLabelText( + 'Auto-assign a VPC IPv4 address for this Linode in the VPC' + ) ).toBeChecked(); }); it('should uncheck the VPC IPv4 if a "ipv4.vpc" is a string value and show the VPC IP TextField', async () => { const { getByLabelText, - getByRole, } = renderWithThemeAndHookFormContext({ component: , useFormOptions: { @@ -135,9 +132,9 @@ describe('VPC', () => { }); expect( - getByRole('checkbox', { - name: 'Auto-assign a VPC IPv4 address for this Linode in the VPC', - }) + getByLabelText( + 'Auto-assign a VPC IPv4 address for this Linode in the VPC' + ) ).not.toBeChecked(); expect(getByLabelText('VPC IPv4 (required)')).toBeVisible(); diff --git a/packages/manager/src/features/Linodes/LinodeCreate/index.test.tsx b/packages/manager/src/features/Linodes/LinodeCreate/index.test.tsx index dbde52b4812..7e53195eacc 100644 --- a/packages/manager/src/features/Linodes/LinodeCreate/index.test.tsx +++ b/packages/manager/src/features/Linodes/LinodeCreate/index.test.tsx @@ -23,10 +23,10 @@ describe('Linode Create', () => { }); it('Should not render the region select when creating from a backup', () => { - const { queryByLabelText } = renderWithTheme(, { + const { queryByText } = renderWithTheme(, { MemoryRouter: { initialEntries: ['/linodes/create?type=Backups'] }, }); - expect(queryByLabelText('Region')).toBeNull(); + expect(queryByText('Region')).toBeNull(); }); }); diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx index 6e82eb2be09..8eebfcc782b 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeNetworking/LinodeIPAddressRow.test.tsx @@ -1,4 +1,4 @@ -import userEvent from '@testing-library/user-event'; +import { fireEvent } from '@testing-library/react'; import * as React from 'react'; import { LinodeConfigInterfaceFactoryWithVPC } from 'src/factories/linodeConfigInterfaceFactory'; @@ -29,8 +29,8 @@ const handlers: IPAddressRowHandlers = { }; describe('LinodeIPAddressRow', () => { - it('should render a Linode IP Address row', async () => { - const { getAllByText, getByLabelText } = renderWithTheme( + it('should render a Linode IP Address row', () => { + const { getAllByText } = renderWithTheme( wrapWithTableBody( { ) ); - // open the action menu - await userEvent.click( - getByLabelText('Action menu for IP Address [object Object]') - ); - getAllByText(ipDisplay.address); getAllByText(ipDisplay.type); getAllByText(ipDisplay.gateway); @@ -77,7 +72,7 @@ describe('LinodeIPAddressRow', () => { }); it('should disable the row if disabled is true and display a tooltip', async () => { - const { getAllByLabelText, getByLabelText, getByTestId } = renderWithTheme( + const { findByRole, getByTestId } = renderWithTheme( wrapWithTableBody( { ) ); - // open the action menu - await userEvent.click( - getByLabelText('Action menu for IP Address [object Object]') - ); - - const deleteBtn = getByTestId('Delete'); + const deleteBtn = getByTestId('action-menu-item-delete'); expect(deleteBtn).toHaveAttribute('aria-disabled', 'true'); + fireEvent.mouseEnter(deleteBtn); + const publicIpsUnassignedTooltip = await findByRole('tooltip'); + expect(publicIpsUnassignedTooltip).toContainHTML( + PUBLIC_IP_ADDRESSES_TOOLTIP_TEXT + ); - const editRDNSBtn = getByTestId('Edit RDNS'); + const editRDNSBtn = getByTestId('action-menu-item-edit-rdns'); expect(editRDNSBtn).toHaveAttribute('aria-disabled', 'true'); - expect(getAllByLabelText(PUBLIC_IP_ADDRESSES_TOOLTIP_TEXT)).toHaveLength(2); + fireEvent.mouseEnter(editRDNSBtn); + const publicIpsUnassignedTooltip2 = await findByRole('tooltip'); + expect(publicIpsUnassignedTooltip2).toContainHTML( + PUBLIC_IP_ADDRESSES_TOOLTIP_TEXT + ); }); - it('should not disable the row if disabled is false', async () => { - const { getByLabelText, getByTestId } = renderWithTheme( + it('should not disable the row if disabled is false', () => { + const { getAllByRole } = renderWithTheme( wrapWithTableBody( { ) ); - // open the action menu - await userEvent.click( - getByLabelText('Action menu for IP Address [object Object]') - ); + const buttons = getAllByRole('button'); - expect(getByTestId('Delete')).toBeEnabled(); + const deleteBtn = buttons[1]; + expect(deleteBtn).not.toHaveAttribute('aria-disabled', 'true'); - expect(getByTestId('Edit RDNS')).toBeEnabled(); + const editRDNSBtn = buttons[3]; + expect(editRDNSBtn).not.toHaveAttribute('aria-disabled', 'true'); }); }); diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/VPCPanel.test.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/VPCPanel.test.tsx index dda6abc4339..2255e3115ec 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/VPCPanel.test.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/VPCPanel.test.tsx @@ -212,9 +212,9 @@ describe('VPCPanel', () => { await waitFor(() => { expect( - wrapper.getByRole('checkbox', { - name: 'Auto-assign a VPC IPv4 address for this Linode in the VPC', - }) + wrapper.getByLabelText( + 'Auto-assign a VPC IPv4 address for this Linode in the VPC' + ) ).not.toBeChecked(); // Using regex here to account for the "(required)" indicator. expect(wrapper.getByLabelText(/^VPC IPv4.*/)).toHaveValue('10.0.4.3'); @@ -244,9 +244,7 @@ describe('VPCPanel', () => { await waitFor(() => { expect( - wrapper.getByRole('checkbox', { - name: 'Assign a public IPv4 address for this Linode', - }) + wrapper.getByLabelText('Assign a public IPv4 address for this Linode') ).toBeChecked(); }); }); diff --git a/packages/manager/src/features/NodeBalancers/NodeBalancerConfigPanel.test.tsx b/packages/manager/src/features/NodeBalancers/NodeBalancerConfigPanel.test.tsx index 064e76f616b..fa06be32953 100644 --- a/packages/manager/src/features/NodeBalancers/NodeBalancerConfigPanel.test.tsx +++ b/packages/manager/src/features/NodeBalancers/NodeBalancerConfigPanel.test.tsx @@ -85,7 +85,6 @@ const proxyProtocol = 'Proxy Protocol'; describe('NodeBalancerConfigPanel', () => { it('renders the NodeBalancerConfigPanel', () => { const { - getAllByLabelText, getByLabelText, getByText, queryByLabelText, @@ -102,13 +101,7 @@ describe('NodeBalancerConfigPanel', () => { expect(getByLabelText('Label')).toBeVisible(); expect(getByLabelText('IP Address')).toBeVisible(); expect(getByLabelText('Weight')).toBeVisible(); - - const portTextFields = getAllByLabelText('Port'); - expect(portTextFields).toHaveLength(2); // There is a port field for the config and a port field for the one node - for (const field of portTextFields) { - expect(field).toBeVisible(); - } - + expect(getByLabelText('Port')).toBeVisible(); expect(getByText('Listen on this port.')).toBeVisible(); expect(getByText('Active Health Checks')).toBeVisible(); expect( diff --git a/packages/manager/src/features/NodeBalancers/NodeBalancerDetail/NodeBalancerConfigurations.test.tsx b/packages/manager/src/features/NodeBalancers/NodeBalancerDetail/NodeBalancerConfigurations.test.tsx index d4480664a67..d82c1156bf9 100644 --- a/packages/manager/src/features/NodeBalancers/NodeBalancerDetail/NodeBalancerConfigurations.test.tsx +++ b/packages/manager/src/features/NodeBalancers/NodeBalancerDetail/NodeBalancerConfigurations.test.tsx @@ -44,15 +44,13 @@ describe('NodeBalancerConfigurations', () => { }) ); - const { - getAllByLabelText, - getByLabelText, - getByTestId, - getByText, - } = renderWithTheme(, { - MemoryRouter: memoryRouter, - routePath, - }); + const { getByLabelText, getByTestId, getByText } = renderWithTheme( + , + { + MemoryRouter: memoryRouter, + routePath, + } + ); expect(getByTestId(loadingTestId)).toBeInTheDocument(); @@ -67,11 +65,7 @@ describe('NodeBalancerConfigurations', () => { expect(getByLabelText('Label')).toBeInTheDocument(); expect(getByLabelText('IP Address')).toBeInTheDocument(); expect(getByLabelText('Weight')).toBeInTheDocument(); - const portTextFields = getAllByLabelText('Port'); - expect(portTextFields).toHaveLength(2); // There is a port field for the config and a port field for the one node - for (const field of portTextFields) { - expect(field).toBeInTheDocument(); - } + expect(getByLabelText('Port')).toBeInTheDocument(); expect(getByText('Listen on this port.')).toBeInTheDocument(); expect(getByText('Active Health Checks')).toBeInTheDocument(); expect( diff --git a/packages/manager/src/features/NodeBalancers/NodeBalancersLanding/NodeBalancerActionMenu.test.tsx b/packages/manager/src/features/NodeBalancers/NodeBalancersLanding/NodeBalancerActionMenu.test.tsx index 61407c83bf6..e950688d3d4 100644 --- a/packages/manager/src/features/NodeBalancers/NodeBalancersLanding/NodeBalancerActionMenu.test.tsx +++ b/packages/manager/src/features/NodeBalancers/NodeBalancersLanding/NodeBalancerActionMenu.test.tsx @@ -12,14 +12,13 @@ const props = { }; describe('NodeBalancerActionMenu', () => { - it('renders the NodeBalancerActionMenu', async () => { - const { getByLabelText, getByText } = renderWithTheme( - - ); + afterEach(() => { + vi.resetAllMocks(); + }); - // Open the Action Menu - await userEvent.click( - getByLabelText(`Action menu for NodeBalancer ${props.nodeBalancerId}`) + it('renders the NodeBalancerActionMenu', () => { + const { getByText } = renderWithTheme( + ); expect(getByText('Configurations')).toBeVisible(); @@ -28,15 +27,10 @@ describe('NodeBalancerActionMenu', () => { }); it('triggers the action to delete the NodeBalancer', async () => { - const { getByLabelText, getByText } = renderWithTheme( + const { getByText } = renderWithTheme( ); - // Open the Action Menu - await userEvent.click( - getByLabelText(`Action menu for NodeBalancer ${props.nodeBalancerId}`) - ); - const deleteButton = getByText('Delete'); await userEvent.click(deleteButton); expect(props.toggleDialog).toHaveBeenCalled(); diff --git a/packages/manager/src/features/NodeBalancers/NodeBalancersLanding/NodeBalancerTableRow.test.tsx b/packages/manager/src/features/NodeBalancers/NodeBalancersLanding/NodeBalancerTableRow.test.tsx index 32d60ff80d6..21b88f7e9a6 100644 --- a/packages/manager/src/features/NodeBalancers/NodeBalancersLanding/NodeBalancerTableRow.test.tsx +++ b/packages/manager/src/features/NodeBalancers/NodeBalancersLanding/NodeBalancerTableRow.test.tsx @@ -20,19 +20,11 @@ describe('NodeBalancerTableRow', () => { vi.resetAllMocks(); }); - it('renders the NodeBalancer table row', async () => { - const { getByLabelText, getByText } = renderWithTheme( - - ); + it('renders the NodeBalancer table row', () => { + const { getByText } = renderWithTheme(); expect(getByText('nodebalancer-id-1')).toBeVisible(); expect(getByText('0.0.0.0')).toBeVisible(); - - // Open the Action Menu - await userEvent.click( - getByLabelText(`Action menu for NodeBalancer ${props.id}`) - ); - expect(getByText('Configurations')).toBeVisible(); expect(getByText('Settings')).toBeVisible(); expect(getByText('Delete')).toBeVisible(); diff --git a/packages/manager/src/features/Profile/OAuthClients/CreateOAuthClientDrawer.test.tsx b/packages/manager/src/features/Profile/OAuthClients/CreateOAuthClientDrawer.test.tsx index 1697d16479f..59d5955191f 100644 --- a/packages/manager/src/features/Profile/OAuthClients/CreateOAuthClientDrawer.test.tsx +++ b/packages/manager/src/features/Profile/OAuthClients/CreateOAuthClientDrawer.test.tsx @@ -27,11 +27,11 @@ describe('Create API Token Drawer', () => { getByText('Cancel'); }); it('Should show client side validation errors', async () => { - const { getByRole, getByText } = renderWithTheme( + const { getByText } = renderWithTheme( ); - const submit = getByRole('button', { name: 'Create' }); + const submit = getByText('Create'); await userEvent.click(submit); @@ -47,7 +47,7 @@ describe('Create API Token Drawer', () => { }) ); - const { getAllByTestId, getByRole } = renderWithTheme( + const { getAllByTestId, getByText } = renderWithTheme( ); @@ -56,7 +56,7 @@ describe('Create API Token Drawer', () => { const labelField = textFields[0]; const callbackUrlField = textFields[1]; - const submit = getByRole('button', { name: 'Create' }); + const submit = getByText('Create'); await userEvent.type(labelField, 'my-oauth-client'); await userEvent.type(callbackUrlField, 'http://localhost:3000'); diff --git a/packages/manager/src/features/Volumes/VolumeCreate.test.tsx b/packages/manager/src/features/Volumes/VolumeCreate.test.tsx index 57352b996da..0e611ed9fb7 100644 --- a/packages/manager/src/features/Volumes/VolumeCreate.test.tsx +++ b/packages/manager/src/features/Volumes/VolumeCreate.test.tsx @@ -55,6 +55,6 @@ describe('VolumeCreate', () => { flags: { blockStorageEncryption: true }, }); - await findByText(encryptVolumeSectionHeader, {}, { timeout: 5_000 }); + await findByText(encryptVolumeSectionHeader); }); }); diff --git a/packages/manager/src/utilities/omittedProps.test.tsx b/packages/manager/src/utilities/omittedProps.test.tsx index b8921875e9e..56a046e1220 100644 --- a/packages/manager/src/utilities/omittedProps.test.tsx +++ b/packages/manager/src/utilities/omittedProps.test.tsx @@ -35,7 +35,7 @@ describe('omittedProps utility', () => { expect(component).not.toHaveAttribute('extraProp'); expect(component).not.toHaveAttribute('anotherProp'); - expect(component).toHaveStyle('color: red'); + expect(component).toHaveStyle('color: rgb(255, 0, 0)'); }); }); diff --git a/packages/manager/vite.config.ts b/packages/manager/vite.config.ts index 296323066bc..afab3254c56 100644 --- a/packages/manager/vite.config.ts +++ b/packages/manager/vite.config.ts @@ -37,7 +37,8 @@ export default defineConfig({ 'src/**/*.utils.{js,jsx,ts,tsx}', ], }, - environment: 'happy-dom', + pool: 'forks', + environment: 'jsdom', globals: true, setupFiles: './src/testSetup.ts', }, diff --git a/packages/ui/.changeset/pr-11085-tests-1728657169966.md b/packages/ui/.changeset/pr-11085-tests-1728657169966.md deleted file mode 100644 index 107ae6b952a..00000000000 --- a/packages/ui/.changeset/pr-11085-tests-1728657169966.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/ui": Tests ---- - -Use `happy-dom` instead of `jsdom` in unit tests ([#11085](https://github.com/linode/manager/pull/11085)) diff --git a/packages/ui/src/components/BetaChip/BetaChip.test.tsx b/packages/ui/src/components/BetaChip/BetaChip.test.tsx index 4f922765477..c4da709edd5 100644 --- a/packages/ui/src/components/BetaChip/BetaChip.test.tsx +++ b/packages/ui/src/components/BetaChip/BetaChip.test.tsx @@ -18,7 +18,7 @@ describe('BetaChip', () => { const { getByTestId } = render(); const betaChip = getByTestId('betaChip'); expect(betaChip).toBeInTheDocument(); - expect(betaChip).toHaveStyle('background-color: #1976d2'); + expect(betaChip).toHaveStyle('background-color: rgb(25, 118, 210)'); }); it('triggers an onClick callback', () => { diff --git a/packages/ui/vitest.config.ts b/packages/ui/vitest.config.ts index c4ce34c1442..95754d431b5 100644 --- a/packages/ui/vitest.config.ts +++ b/packages/ui/vitest.config.ts @@ -2,7 +2,7 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { - environment: 'happy-dom', + environment: 'jsdom', setupFiles: './testSetup.ts', }, }); diff --git a/yarn.lock b/yarn.lock index 7fef5d8b381..39b3c3fa612 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2922,6 +2922,13 @@ acorn@^8.12.0, acorn@^8.12.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== +agent-base@^7.0.2, agent-base@^7.1.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317" + integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA== + dependencies: + debug "^4.3.4" + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -4008,6 +4015,13 @@ 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== +cssstyle@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-4.1.0.tgz#161faee382af1bafadb6d3867a92a19bcb4aea70" + integrity sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA== + dependencies: + rrweb-cssom "^0.7.1" + csstype@^2.5.7: version "2.6.21" resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.21.tgz#2efb85b7cc55c80017c66a5ad7cbd931fda3a90e" @@ -4172,6 +4186,14 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +data-urls@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-5.0.0.tgz#2f76906bce1824429ffecb6920f45a0b30f00dde" + integrity sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg== + dependencies: + whatwg-mimetype "^4.0.0" + whatwg-url "^14.0.0" + data-view-buffer@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2" @@ -4211,6 +4233,13 @@ debug@2.6.9: dependencies: ms "2.0.0" +debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6, debug@~4.3.6: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + debug@^3.1.0: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -4218,18 +4247,16 @@ debug@^3.1.0: dependencies: ms "^2.1.1" -debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6, debug@~4.3.6: - version "4.3.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" - integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== - dependencies: - ms "^2.1.3" - decimal.js-light@^2.4.1: version "2.5.1" resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== +decimal.js@^10.4.3: + version "10.4.3" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" + integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== + decode-named-character-reference@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e" @@ -4456,7 +4483,7 @@ enquirer@^2.3.5, enquirer@^2.3.6: ansi-colors "^4.1.1" strip-ansi "^6.0.1" -entities@^4.4.0, entities@^4.5.0: +entities@^4.4.0: version "4.5.0" resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== @@ -5788,15 +5815,6 @@ graphql@^16.8.1: resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.9.0.tgz#1c310e63f16a49ce1fbb230bd0a000e99f6f115f" integrity sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw== -happy-dom@^15.7.4: - version "15.7.4" - resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-15.7.4.tgz#05aade59c1d307336001b7004c76dfc6a829f220" - integrity sha512-r1vadDYGMtsHAAsqhDuk4IpPvr6N8MGKy5ntBo7tSdim+pWDxus2PNqOcOt8LuDZ4t3KJHE+gCuzupcx/GKnyQ== - dependencies: - entities "^4.5.0" - webidl-conversions "^7.0.0" - whatwg-mimetype "^3.0.0" - has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" @@ -5918,6 +5936,13 @@ hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react- dependencies: react-is "^16.7.0" +html-encoding-sniffer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz#696df529a7cfd82446369dc5193e590a3735b448" + integrity sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ== + dependencies: + whatwg-encoding "^3.1.1" + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -5947,6 +5972,14 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +http-proxy-agent@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" + integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== + dependencies: + agent-base "^7.1.0" + debug "^4.3.4" + http-signature@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.4.0.tgz#dee5a9ba2bf49416abc544abd6d967f6a94c8c3f" @@ -5956,6 +5989,14 @@ http-signature@~1.4.0: jsprim "^2.0.2" sshpk "^1.18.0" +https-proxy-agent@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz#9e8b5013873299e11fab6fd548405da2d6c602b2" + integrity sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw== + dependencies: + agent-base "^7.0.2" + debug "4" + human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -5983,6 +6024,13 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + ieee754@^1.1.13: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -6307,6 +6355,11 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -6519,6 +6572,33 @@ jsdoc-type-pratt-parser@^4.0.0: resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz#ff6b4a3f339c34a6c188cbf50a16087858d22113" integrity sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg== +jsdom@^24.1.1: + version "24.1.3" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-24.1.3.tgz#88e4a07cb9dd21067514a619e9f17b090a394a9f" + integrity sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ== + dependencies: + cssstyle "^4.0.1" + data-urls "^5.0.0" + decimal.js "^10.4.3" + form-data "^4.0.0" + html-encoding-sniffer "^4.0.0" + http-proxy-agent "^7.0.2" + https-proxy-agent "^7.0.5" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.12" + parse5 "^7.1.2" + rrweb-cssom "^0.7.1" + saxes "^6.0.0" + symbol-tree "^3.2.4" + tough-cookie "^4.1.4" + w3c-xmlserializer "^5.0.0" + webidl-conversions "^7.0.0" + whatwg-encoding "^3.1.1" + whatwg-mimetype "^4.0.0" + whatwg-url "^14.0.0" + ws "^8.18.0" + xml-name-validator "^5.0.0" + jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -7664,6 +7744,11 @@ npm-run-path@^5.1.0: dependencies: path-key "^4.0.0" +nwsapi@^2.2.12: + version "2.2.12" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.12.tgz#fb6af5c0ec35b27b4581eb3bbad34ec9e5c696f8" + integrity sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w== + object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -7870,6 +7955,13 @@ parse-json@^5.0.0, parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse5@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== + dependencies: + entities "^4.4.0" + parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -8142,7 +8234,7 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.0, punycode@^2.1.1: +punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== @@ -8769,6 +8861,11 @@ rollup@^4.19.0, rollup@^4.20.0: "@rollup/rollup-win32-x64-msvc" "4.22.4" fsevents "~2.3.2" +rrweb-cssom@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz#c73451a484b86dd7cfb1e0b2898df4b703183e4b" + integrity sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg== + run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" @@ -8819,7 +8916,7 @@ safe-regex-test@^1.0.3: es-errors "^1.3.0" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -8829,6 +8926,13 @@ sax@>=0.6.0: resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.1.tgz#44cc8988377f126304d3b3fc1010c733b929ef0f" integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== +saxes@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5" + integrity sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA== + dependencies: + xmlchars "^2.2.0" + scheduler@^0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.18.0.tgz#5901ad6659bc1d8f3fdaf36eb7a67b0d6746b1c4" @@ -9380,6 +9484,11 @@ symbol-observable@^1.0.4: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + table@^5.2.3: version "5.4.6" resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" @@ -9562,6 +9671,13 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +tr46@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-5.0.0.tgz#3b46d583613ec7283020d79019f1335723801cec" + integrity sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g== + dependencies: + punycode "^2.3.1" + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -10065,6 +10181,13 @@ vitest@^2.1.1: vite-node "2.1.1" why-is-node-running "^2.3.0" +w3c-xmlserializer@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz#f925ba26855158594d907313cedd1476c5967f6c" + integrity sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA== + dependencies: + xml-name-validator "^5.0.0" + warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" @@ -10092,15 +10215,30 @@ webpack-virtual-modules@^0.6.2: resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8" integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ== +whatwg-encoding@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz#d0f4ef769905d426e1688f3e34381a99b60b76e5" + integrity sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ== + dependencies: + iconv-lite "0.6.3" + whatwg-fetch@>=0.10.0: version "3.6.20" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70" integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg== -whatwg-mimetype@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" - integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== +whatwg-mimetype@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz#bc1bf94a985dc50388d54a9258ac405c3ca2fc0a" + integrity sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg== + +whatwg-url@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-14.0.0.tgz#00baaa7fd198744910c4b1ef68378f2200e4ceb6" + integrity sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw== + dependencies: + tr46 "^5.0.0" + webidl-conversions "^7.0.0" whatwg-url@^5.0.0: version "5.0.0" @@ -10244,11 +10382,16 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" -ws@^8.2.3: +ws@^8.18.0, ws@^8.2.3: version "8.18.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== +xml-name-validator@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-5.0.0.tgz#82be9b957f7afdacf961e5980f1bf227c0bf7673" + integrity sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg== + xml2js@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499" @@ -10267,6 +10410,11 @@ xmlbuilder@~11.0.0: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"