diff --git a/packages/hydrogen/src/components/BuyNowButton/tests/BuyNowButton.test.tsx b/packages/hydrogen/src/components/BuyNowButton/tests/BuyNowButton.test.tsx
deleted file mode 100644
index bb81fd1197..0000000000
--- a/packages/hydrogen/src/components/BuyNowButton/tests/BuyNowButton.test.tsx
+++ /dev/null
@@ -1,173 +0,0 @@
-import React from 'react';
-
-import {mountWithProviders} from '../../../utilities/tests/shopifyMount.js';
-import {BaseButton} from '../../BaseButton/index.js';
-
-const mockCreateInstantCheckout = jest.fn();
-const mockUseInstantCheckout = jest.fn();
-const mockUseCartFetch = jest.fn();
-
-import {BuyNowButton} from '../BuyNowButton.client.js';
-
-jest.mock('../../CartProvider', () => ({
- ...(jest.requireActual('../../CartProvider') as {}),
- useInstantCheckout: mockUseInstantCheckout,
- useCartFetch: mockUseCartFetch,
-}));
-
-describe('BuyNowButton', () => {
- beforeEach(() => {
- mockUseInstantCheckout.mockReturnValue({
- createInstantCheckout: mockCreateInstantCheckout,
- checkoutUrl: undefined,
- });
- });
-
- afterEach(() => {
- jest.clearAllMocks();
- });
-
- it('renders a button', () => {
- const component = mountWithProviders(
- Buy now
- );
- expect(component).toContainReactComponent('button', {
- children: 'Buy now',
- });
- });
-
- it('can optionally disable the button', () => {
- const component = mountWithProviders(
-
- Buy now
-
- );
-
- expect(component).toContainReactComponent('button', {
- disabled: true,
- });
- });
-
- it('allows pass-through props', () => {
- const component = mountWithProviders(
-
- Buy now
-
- );
-
- expect(component).toContainReactComponent('button', {
- className: 'fancy-button',
- });
- });
-
- describe('when the button is clicked', () => {
- it('uses useCartCreateCallback with the correct arguments', () => {
- const component = mountWithProviders(
-
- Buy now
-
- );
-
- component.act(() => {
- component.find('button')?.trigger('onClick');
- });
-
- expect(mockCreateInstantCheckout).toHaveBeenCalledTimes(1);
- expect(mockCreateInstantCheckout).toHaveBeenCalledWith({
- lines: [
- {
- quantity: 4,
- merchandiseId: 'SKU123',
- attributes: [
- {key: 'color', value: 'blue'},
- {key: 'size', value: 'large'},
- ],
- },
- ],
- });
- });
-
- it('disables the button', () => {
- const component = mountWithProviders(
- Buy now
- );
-
- expect(component).toContainReactComponent('button', {
- disabled: false,
- });
-
- component.act(() => {
- component.find('button')?.trigger('onClick');
- });
-
- expect(component.find('button')).toHaveReactProps({disabled: true});
- });
- });
-
- describe('when a checkout URL is available', () => {
- const {location} = window;
- const mockSetHref = jest.fn((href) => href);
-
- beforeEach(() => {
- mockUseInstantCheckout.mockReturnValue({
- createInstantCheckout: mockCreateInstantCheckout,
- checkoutUrl: '/checkout?id=123',
- });
-
- delete (window as Partial).location;
- window.location = {...window.location};
- Object.defineProperty(window.location, 'href', {
- set: mockSetHref,
- });
- });
-
- afterEach(() => {
- window.location = location;
- mockUseInstantCheckout.mockRestore();
- });
-
- it('redirects to checkout', () => {
- mountWithProviders(Buy now);
-
- expect(mockSetHref).toHaveBeenCalledTimes(1);
- expect(mockSetHref).toHaveBeenCalledWith('/checkout?id=123');
- });
- });
-
- describe('BaseButton', () => {
- it('passes the onClick handler', () => {
- const mockOnClick = jest.fn();
-
- const component = mountWithProviders(
-
- Buy now
-
- );
-
- expect(component).toContainReactComponent(BaseButton, {
- onClick: mockOnClick,
- });
- });
-
- it('passes the buttonRef', () => {
- const mockRef = React.createRef();
-
- const component = mountWithProviders(
-
- Buy now
-
- );
-
- expect(component).toContainReactComponent(BaseButton, {
- buttonRef: mockRef,
- });
- });
- });
-});
diff --git a/packages/hydrogen/src/components/BuyNowButton/tests/BuyNowButton.vitest.tsx b/packages/hydrogen/src/components/BuyNowButton/tests/BuyNowButton.vitest.tsx
new file mode 100644
index 0000000000..0f7b72f9a7
--- /dev/null
+++ b/packages/hydrogen/src/components/BuyNowButton/tests/BuyNowButton.vitest.tsx
@@ -0,0 +1,145 @@
+import React from 'react';
+import {ShopifyTestProviders} from '../../../utilities/tests/provider-helpers.js';
+import {render, screen} from '@testing-library/react';
+import {vi} from 'vitest';
+import userEvent from '@testing-library/user-event';
+
+const mockCreateInstantCheckout = vi.fn();
+const mockUseInstantCheckout = vi.fn();
+const mockUseCartFetch = vi.fn();
+
+import {BuyNowButton} from '../BuyNowButton.client.js';
+
+vi.mock('../../CartProvider/index.js', () => ({
+ ...(vi.importActual('../../CartProvider/index.js') as {}),
+ useInstantCheckout: mockUseInstantCheckout,
+ useCartFetch: mockUseCartFetch,
+}));
+
+describe('', () => {
+ beforeEach(() => {
+ mockUseInstantCheckout.mockReturnValue({
+ createInstantCheckout: mockCreateInstantCheckout,
+ checkoutUrl: undefined,
+ });
+ });
+
+ it('renders a button', () => {
+ render(Buy now, {
+ wrapper: ShopifyTestProviders,
+ });
+ expect(screen.getByRole('button')).toHaveTextContent('Buy now');
+ });
+
+ it('can optionally disable the button', () => {
+ render(
+
+ Buy now
+ ,
+ {
+ wrapper: ShopifyTestProviders,
+ }
+ );
+
+ expect(screen.getByRole('button')).toBeDisabled();
+ });
+
+ it('allows pass-through props', () => {
+ render(
+
+ Buy now
+ ,
+ {
+ wrapper: ShopifyTestProviders,
+ }
+ );
+
+ expect(screen.getByRole('button')).toHaveClass('fancy-button');
+ });
+
+ describe('when the button is clicked', () => {
+ it('uses useCartCreateCallback with the correct arguments', async () => {
+ const user = userEvent.setup();
+
+ render(
+
+ Buy now
+ ,
+ {
+ wrapper: ShopifyTestProviders,
+ }
+ );
+
+ await user.click(screen.getByRole('button'));
+
+ expect(mockCreateInstantCheckout).toHaveBeenCalledTimes(1);
+ expect(mockCreateInstantCheckout).toHaveBeenCalledWith({
+ lines: [
+ {
+ quantity: 4,
+ merchandiseId: 'SKU123',
+ attributes: [
+ {key: 'color', value: 'blue'},
+ {key: 'size', value: 'large'},
+ ],
+ },
+ ],
+ });
+ });
+
+ it('disables the button', async () => {
+ const user = userEvent.setup();
+
+ render(Buy now, {
+ wrapper: ShopifyTestProviders,
+ });
+
+ const button = screen.getByRole('button');
+
+ expect(button).not.toBeDisabled();
+
+ await user.click(button);
+
+ expect(button).toBeDisabled();
+ });
+ });
+
+ describe('when a checkout URL is available', () => {
+ const {location} = window;
+ const mockSetHref = vi.fn((href) => href);
+
+ beforeEach(() => {
+ mockUseInstantCheckout.mockReturnValue({
+ createInstantCheckout: mockCreateInstantCheckout,
+ checkoutUrl: '/checkout?id=123',
+ });
+
+ delete (window as Partial).location;
+ window.location = {...window.location};
+ Object.defineProperty(window.location, 'href', {
+ set: mockSetHref,
+ });
+ });
+
+ afterEach(() => {
+ window.location = location;
+ mockUseInstantCheckout.mockRestore();
+ });
+
+ it('redirects to checkout', () => {
+ render(Buy now, {
+ wrapper: ShopifyTestProviders,
+ });
+
+ expect(mockSetHref).toHaveBeenCalledTimes(1);
+ expect(mockSetHref).toHaveBeenCalledWith('/checkout?id=123');
+ });
+ });
+});
diff --git a/packages/hydrogen/src/components/CartCheckoutButton/tests/CartCheckoutButton.test.tsx b/packages/hydrogen/src/components/CartCheckoutButton/tests/CartCheckoutButton.test.tsx
deleted file mode 100644
index c1c594c248..0000000000
--- a/packages/hydrogen/src/components/CartCheckoutButton/tests/CartCheckoutButton.test.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import React from 'react';
-import {CartProvider} from '../../CartProvider/index.js';
-import {CartCheckoutButton} from '../CartCheckoutButton.client.js';
-import {mountWithProviders} from '../../../utilities/tests/shopifyMount.js';
-
-jest.mock('../../CartProvider', () => ({
- ...(jest.requireActual('../../CartProvider') as {}),
- useCart: () => {
- return {
- status: 'idle',
- };
- },
-}));
-
-describe('CartCheckoutButton', () => {
- const fetch = global.fetch;
-
- beforeEach(() => {
- // @ts-ignore
- global.fetch = jest.fn(async (_url, _init) => {
- return {
- json: async () =>
- JSON.stringify({
- data: {},
- }),
- };
- });
- });
-
- afterEach(() => {
- global.fetch = fetch;
- });
-
- // TODO fix this when @shopify/react-testing supports React 18 experimental
- it.skip('redirects to checkout when clicked', () => {
- const button = mountWithProviders(
-
- Checkout
-
- );
-
- Object.defineProperty(window, 'location', {
- value: {
- href: '',
- },
- });
-
- button.act(() => {
- button.find('button')!.trigger('onClick');
- });
-
- expect(window.location.href).toBe('https://shopify.com/checkout');
- });
-});
diff --git a/packages/hydrogen/src/components/CartCheckoutButton/tests/CartCheckoutButton.vitest.tsx b/packages/hydrogen/src/components/CartCheckoutButton/tests/CartCheckoutButton.vitest.tsx
new file mode 100644
index 0000000000..f9d3b7d6bc
--- /dev/null
+++ b/packages/hydrogen/src/components/CartCheckoutButton/tests/CartCheckoutButton.vitest.tsx
@@ -0,0 +1,52 @@
+import React from 'react';
+import {CartProvider} from '../../CartProvider/index.js';
+import {CartCheckoutButton} from '../CartCheckoutButton.client.js';
+import {
+ ShopifyTestProviders,
+ CartTestProviders,
+} from '../../../utilities/tests/provider-helpers.js';
+import {vi} from 'vitest';
+import {render, screen} from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+
+describe('', () => {
+ const fetch = global.fetch;
+
+ beforeEach(() => {
+ // @ts-expect-error custom mock of fetch
+ global.fetch = vi.fn(async (_url, _init) => {
+ return {
+ json: async () =>
+ JSON.stringify({
+ data: {},
+ }),
+ };
+ });
+ });
+
+ afterEach(() => {
+ global.fetch = fetch;
+ });
+
+ it('redirects to checkout when clicked', async () => {
+ const user = userEvent.setup();
+ const checkoutUrl = 'https://shopify.com/checkout';
+
+ render(
+
+ Checkout
+ ,
+ {wrapper: ShopifyTestProviders}
+ );
+
+ Object.defineProperty(window, 'location', {
+ value: {
+ href: '',
+ },
+ });
+
+ await user.click(screen.getByRole('button'));
+
+ expect(window.location.href).toBe(checkoutUrl);
+ });
+});