Skip to content

Commit a2da1ea

Browse files
authored
Merge pull request #1350 from w3bdesign/develop
.
2 parents 980e657 + a23800c commit a2da1ea

File tree

4 files changed

+77
-41
lines changed

4 files changed

+77
-41
lines changed

.github/workflows/playwright.yml

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,36 @@ jobs:
1717
run: npm ci
1818
- name: Install Playwright Browsers
1919
run: npx playwright install --with-deps
20+
- name: Build the project
21+
run: npm run build
22+
env:
23+
NEXT_PUBLIC_GRAPHQL_URL: ${{ secrets.NEXT_PUBLIC_GRAPHQL_URL }}
24+
- name: Start the application
25+
run: npm run start &
26+
env:
27+
NEXT_PUBLIC_GRAPHQL_URL: ${{ secrets.NEXT_PUBLIC_GRAPHQL_URL }}
28+
- name: Wait for the application to be ready
29+
run: |
30+
echo "Waiting for the application to be ready..."
31+
timeout 300 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:3000)" != "200" ]]; do sleep 5; done' || false
32+
echo "Application is ready!"
2033
- name: Run Playwright tests
2134
run: npx playwright test
2235
env:
23-
CI: true
24-
NEXT_PUBLIC_GRAPHQL_URL: ${{ secrets.NEXT_PUBLIC_GRAPHQL_URL }}
25-
- uses: actions/upload-artifact@v4
36+
CI: true
37+
NEXT_PUBLIC_GRAPHQL_URL: ${{ secrets.NEXT_PUBLIC_GRAPHQL_URL }}
38+
DEBUG: pw:api
39+
- name: Upload test results
2640
if: always()
41+
uses: actions/upload-artifact@v4
2742
with:
2843
name: playwright-report
2944
path: playwright-report/
3045
retention-days: 30
46+
- name: Upload test traces
47+
if: failure()
48+
uses: actions/upload-artifact@v4
49+
with:
50+
name: playwright-traces
51+
path: test-results/
52+
retention-days: 30

playwright.config.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ import { devices } from '@playwright/test';
1212
const config: PlaywrightTestConfig = {
1313
testDir: './src/tests',
1414
/* Maximum time one test can run for. */
15-
timeout: 30 * 1000,
15+
timeout: 60 * 1000, // Increased to 60 seconds
1616
expect: {
1717
/**
1818
* Maximum time expect() should wait for the condition to be met.
1919
* For example in `await expect(locator).toHaveText();`
2020
*/
21-
timeout: 15000,
21+
timeout: 30000, // Increased to 30 seconds
2222
},
2323
/* Run tests in files in parallel */
2424
fullyParallel: true,
@@ -33,7 +33,7 @@ const config: PlaywrightTestConfig = {
3333
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
3434
use: {
3535
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
36-
actionTimeout: 0,
36+
actionTimeout: 30000, // Added 30 second timeout for actions
3737
/* Base URL to use in actions like `await page.goto('/')`. */
3838
baseURL: 'http://localhost:3000',
3939

@@ -103,6 +103,7 @@ const config: PlaywrightTestConfig = {
103103
reuseExistingServer: true,
104104
command: 'npm run dev',
105105
port: 3000,
106+
timeout: 120000, // Added 2 minute timeout for server start
106107
},
107108
};
108109

src/components/Product/AddToCart.component.tsx

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,12 @@ export interface IProductRootObject {
9090
* @param {number} variationId // Variation ID
9191
* @param {boolean} fullWidth // Whether the button should be full-width
9292
*/
93-
9493
const AddToCart = ({
9594
product,
9695
variationId,
9796
fullWidth = false,
9897
}: IProductRootObject) => {
99-
const { setCart } = useContext(CartContext);
98+
const { updateCart } = useContext(CartContext);
10099
const [requestError, setRequestError] = useState<boolean>(false);
101100

102101
const productId = product?.databaseId ? product?.databaseId : variationId;
@@ -107,20 +106,14 @@ const AddToCart = ({
107106
};
108107

109108
// Get cart data query
110-
const { data, refetch } = useQuery(GET_CART, {
109+
const { refetch } = useQuery(GET_CART, {
111110
notifyOnNetworkStatusChange: true,
112-
onCompleted: () => {
113-
// Update cart in the localStorage.
111+
onCompleted: (data) => {
112+
// Update cart in the localStorage and React Context.
114113
const updatedCart = getFormattedCart(data);
115-
116-
if (!updatedCart) {
117-
return;
114+
if (updatedCart) {
115+
updateCart(updatedCart);
118116
}
119-
120-
localStorage.setItem('woocommerce-cart', JSON.stringify(updatedCart));
121-
122-
// Update cart data in React Context.
123-
setCart(updatedCart);
124117
},
125118
});
126119

@@ -129,34 +122,43 @@ const AddToCart = ({
129122
variables: {
130123
input: productQueryInput,
131124
},
132-
133-
onCompleted: () => {
134-
// Update the cart with new values in React context.
135-
refetch();
125+
onCompleted: (data) => {
126+
// Immediately update the cart with new values
127+
const updatedCart = getFormattedCart(data);
128+
if (updatedCart) {
129+
updateCart(updatedCart);
130+
}
136131
},
137-
138132
onError: () => {
139133
setRequestError(true);
140134
},
141135
});
142136

143-
const handleAddToCart = () => {
144-
addToCart();
145-
// Refetch cart after 2 seconds
146-
setTimeout(() => {
147-
refetch();
148-
}, 2000);
137+
const handleAddToCart = async () => {
138+
try {
139+
await addToCart();
140+
// Refetch cart immediately after adding to cart
141+
await refetch();
142+
} catch (error) {
143+
setRequestError(true);
144+
}
149145
};
150146

151147
return (
152148
<>
153149
<Button
154-
handleButtonClick={() => handleAddToCart()}
150+
handleButtonClick={handleAddToCart}
155151
buttonDisabled={addToCartLoading || requestError}
156152
fullWidth={fullWidth}
157153
>
158154
KJØP
159155
</Button>
156+
{requestError && (
157+
<p>
158+
Det oppstod en feil ved tillegging i handlekurven. Vennligst prøv
159+
igjen.
160+
</p>
161+
)}
160162
</>
161163
);
162164
};

src/stores/CartProvider.tsx

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import React, {
66
JSXElementConstructor,
77
ReactFragment,
88
ReactPortal,
9+
useMemo,
910
} from 'react';
1011

1112
interface ICartProviderProps {
@@ -49,37 +50,47 @@ export type TRootObjectNull = RootObject | null | undefined;
4950
interface ICartContext {
5051
cart: RootObject | null | undefined;
5152
setCart: React.Dispatch<React.SetStateAction<TRootObjectNull>>;
53+
updateCart: (newCart: RootObject) => void;
5254
}
5355

54-
const CartState = {
56+
const CartState: ICartContext = {
5557
cart: null,
5658
setCart: () => {},
59+
updateCart: () => {},
5760
};
5861

5962
export const CartContext = createContext<ICartContext>(CartState);
6063

6164
/**
6265
* Provides a global application context for the entire application with the cart contents
63-
6466
*/
6567
export const CartProvider = ({ children }: ICartProviderProps) => {
6668
const [cart, setCart] = useState<RootObject | null>();
6769

6870
useEffect(() => {
6971
// Check if we are client-side before we access the localStorage
70-
if (!process.browser) {
71-
return;
72+
if (typeof window !== 'undefined') {
73+
const localCartData = localStorage.getItem('woocommerce-cart');
74+
if (localCartData) {
75+
const cartData: RootObject = JSON.parse(localCartData);
76+
setCart(cartData);
77+
}
7278
}
73-
const localCartData = localStorage.getItem('woocommerce-cart');
79+
}, []);
7480

75-
if (localCartData) {
76-
const cartData: RootObject = JSON.parse(localCartData);
77-
setCart(cartData);
81+
const updateCart = (newCart: RootObject) => {
82+
setCart(newCart);
83+
if (typeof window !== 'undefined') {
84+
localStorage.setItem('woocommerce-cart', JSON.stringify(newCart));
7885
}
79-
}, []);
86+
};
87+
88+
const contextValue = useMemo(() => {
89+
return { cart, setCart, updateCart };
90+
}, [cart]);
8091

8192
return (
82-
<CartContext.Provider value={{ cart, setCart }}>
93+
<CartContext.Provider value={contextValue}>
8394
{children}
8495
</CartContext.Provider>
8596
);

0 commit comments

Comments
 (0)