Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion apps/main/__tests__/e2e-fixtures.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isRouteTeardownError } from '../e2e/fixtures';
import { isRouteTeardownError } from '../e2e/route-errors';

describe('isRouteTeardownError', () => {
it('recognizes Playwright route callbacks that fail because the page closed', () => {
Expand All @@ -11,6 +11,26 @@ describe('isRouteTeardownError', () => {
).toBe(true);
});

it('recognizes Playwright route callbacks that outlive the test', () => {
expect(
isRouteTeardownError(
new Error(
"route.fetch: Test ended. Consider awaiting `await page.unrouteAll({ behavior: 'ignoreErrors' })` before the end of the test to ignore remaining routes in flight."
)
)
).toBe(true);
expect(isRouteTeardownError(new Error('apiResponse.json: Response has been disposed'))).toBe(
true
);
expect(
isRouteTeardownError(
new Error(
'browserContext.close: Protocol error (Target.disposeBrowserContext): Failed to find context with id 513C879CBD62230DCD877196EE9BEC01'
)
)
).toBe(true);
});

it('does not hide unrelated route failures', () => {
expect(isRouteTeardownError(new Error('route.fetch: connect ECONNREFUSED'))).toBe(false);
});
Expand Down
19 changes: 9 additions & 10 deletions apps/main/e2e/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {

import { restoreOPFS } from './opfs-helpers';
import { restoreLocalStorage, type SavedAuthState } from './indexeddb-helpers';
import { isRouteTeardownError } from './route-errors';

import type { StoreVariant, WcposTestOptions } from '../playwright.config';

Expand All @@ -28,14 +29,7 @@ const APP_PACKAGE_VERSION = JSON.parse(
fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8')
).version;
const VERSION_STUBBED_CONTEXTS = new WeakSet<BrowserContext>();

export function isRouteTeardownError(error: unknown): boolean {
if (!(error instanceof Error)) {
return false;
}

return error.message.includes('Target page, context or browser has been closed');
}
export { isRouteTeardownError } from './route-errors';

/**
* Get the store URL from the project config, with env var override.
Expand Down Expand Up @@ -595,7 +589,12 @@ export const authenticatedTest = base.extend<{ posPage: Page }>({
await authenticateWithStore(page, testInfo);
}

// eslint-disable-next-line react-hooks/rules-of-hooks -- Playwright fixture API, not a React hook
await use(page);
try {
// eslint-disable-next-line react-hooks/rules-of-hooks -- Playwright fixture API, not a React hook
await use(page);
} finally {
await page.unrouteAll({ behavior: 'ignoreErrors' }).catch(() => {});
await page.context().unrouteAll({ behavior: 'ignoreErrors' }).catch(() => {});
}
},
});
16 changes: 16 additions & 0 deletions apps/main/e2e/route-errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const ROUTE_TEARDOWN_ERROR_MESSAGES = [
'Target page, context or browser has been closed',
'Test ended',
'Response has been disposed',
'Target.disposeBrowserContext',
];

export function isRouteTeardownError(error: unknown): boolean {
if (!(error instanceof Error)) {
return false;
}

return ROUTE_TEARDOWN_ERROR_MESSAGES.some((message) =>
error.message.includes(message)
);
}
2 changes: 1 addition & 1 deletion apps/main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
},
"devDependencies": {
"@babel/core": "^7.29.7",
"@playwright/test": "^1.60.0",
"@playwright/test": "^1.61.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@types/react": "^19.2.17",
Expand Down
4 changes: 2 additions & 2 deletions apps/template-studio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
"jsdom": "^26.1.0",
"playwright": "1.60.0",
"playwright": "1.61.1",
"tsx": "^4.22.4",
"vitest": "^4.1.8"
"vitest": "^4.1.9"
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"eslint": "^9.39.4",
"expo": "~56.0.11",
"glob": "^13.0.6",
"lint-staged": "^16.4.0",
"lint-staged": "^17.0.8",
"prettier-plugin-tailwindcss": "^0.8.0"
},
"dependencies": {
Expand Down
3 changes: 1 addition & 2 deletions packages/components/src/combobox/combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ function Combobox<T = undefined>({
prop: valueProp as Option<any> | Option<any>[] | undefined,
defaultProp: defaultValue as Option<any> | Option<any>[] | undefined,
onChange: onValueChangeProp as
| ((value: Option<any> | Option<any>[] | undefined) => void)
| undefined,
((value: Option<any> | Option<any>[] | undefined) => void) | undefined,
});
const [filterValue, setFilterValue] = React.useState('');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ interface ErrorBoundaryPropsWithFallback {
}

type ErrorBoundaryProps =
| ErrorBoundaryPropsWithFallback
| ErrorBoundaryPropsWithComponent
| ErrorBoundaryPropsWithRender;
ErrorBoundaryPropsWithFallback | ErrorBoundaryPropsWithComponent | ErrorBoundaryPropsWithRender;

type ErrorBoundaryState = { error: Error | null };

Expand Down
3 changes: 1 addition & 2 deletions packages/components/src/form/combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import type { FormItemProps } from './common';
* Multi-select: value is Option[], passed through directly.
*/
type FormComboboxProps = (
| (FormItemProps<string> & { multiple?: false })
| (FormItemProps<Option[]> & { multiple: true })
(FormItemProps<string> & { multiple?: false }) | (FormItemProps<Option[]> & { multiple: true })
) &
Omit<Partial<React.ComponentProps<typeof Combobox>>, 'value' | 'onValueChange' | 'multiple'>;

Expand Down
3 changes: 1 addition & 2 deletions packages/components/src/form/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import type { FormItemProps } from './common';
* Multi-select: value is Option[], passed through directly.
*/
type FormSelectProps = (
| (FormItemProps<string> & { multiple?: false })
| (FormItemProps<Option[]> & { multiple: true })
(FormItemProps<string> & { multiple?: false }) | (FormItemProps<Option[]> & { multiple: true })
) &
Omit<Partial<React.ComponentProps<typeof Select>>, 'value' | 'onValueChange' | 'multiple'>;

Expand Down
3 changes: 1 addition & 2 deletions packages/components/src/tree-combobox/tree-combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,7 @@ function TreeCombobox<T = undefined>({
prop: valueProp as ComboboxOption | ComboboxOption[] | undefined,
defaultProp: defaultValue as ComboboxOption | ComboboxOption[] | undefined,
onChange: onValueChangeProp as
| ((v: ComboboxOption | ComboboxOption[] | undefined) => void)
| undefined,
((v: ComboboxOption | ComboboxOption[] | undefined) => void) | undefined,
});

const isSelected = React.useCallback(
Expand Down
3 changes: 1 addition & 2 deletions packages/components/src/tree-combobox/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ export type TreeComboboxMultiProps<T = undefined> = TreeComboboxBaseProps<T> & {
};

export type TreeComboboxProps<T = undefined> =
| TreeComboboxSingleProps<T>
| TreeComboboxMultiProps<T>;
TreeComboboxSingleProps<T> | TreeComboboxMultiProps<T>;

// --- Content props ---

Expand Down
3 changes: 1 addition & 2 deletions packages/core/src/hooks/use-wcpos-auth/index.web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ function parseAuthFromUrl(): WcposAuthResult | null {
if (result.type === 'success' && result.params) {
const savedState = getSavedCsrfState();
const returnedState = (result.params as unknown as Record<string, unknown>)?.state as
| string
| undefined;
string | undefined;

if (savedState && returnedState !== savedState) {
oauthLogger.error('State parameter mismatch - possible CSRF attack');
Expand Down
8 changes: 1 addition & 7 deletions packages/core/src/screens/auth/hooks/use-site-connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,7 @@ interface ExtendedSiteData extends WpJsonResponse {
}

export type SiteConnectStatus =
| 'idle'
| 'discovering-url'
| 'discovering-api'
| 'testing-auth'
| 'saving'
| 'success'
| 'error';
'idle' | 'discovering-url' | 'discovering-api' | 'testing-auth' | 'saving' | 'success' | 'error';

export interface SiteConnectProgress {
step: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ export function DrawerItemList({ state, navigation, descriptors }: DrawerContent
key={route.key}
label={
(drawerLabel !== undefined ? drawerLabel : title !== undefined ? title : route.name) as
| string
| ((props: { focused?: boolean; color?: string }) => React.ReactNode)
string | ((props: { focused?: boolean; color?: string }) => React.ReactNode)
}
icon={
drawerIcon as
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,11 @@ export function VariableProductPrice({
}: CellContext<{ document: ProductDocument }, 'price' | 'regular_price' | 'sale_price'>) {
const product = row.original.document;
const taxStatus = useObservableState(product.tax_status$!, product.tax_status) as
| 'none'
| 'taxable'
| 'shipping'
| undefined;
'none' | 'taxable' | 'shipping' | undefined;
const taxClass = useObservableState(product.tax_class$!, product.tax_class) as string | undefined;

const metaData = useObservableState(product.meta_data$!, product.meta_data) as
| { key?: string; value?: string }[]
| undefined;
{ key?: string; value?: string }[] | undefined;
const variablePrices = getVariablePrices(metaData);
const key = column.id as PriceKey;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@ import { convertLocalDateToUTCString } from '../../../../hooks/use-local-date';
const mutationLogger = getLogger(['wcpos', 'mutations', 'local']);

type Document =
| OrderDocument
| ProductDocument
| CustomerDocument
| ProductVariationDocument
| CouponDocument;
OrderDocument | ProductDocument | CustomerDocument | ProductVariationDocument | CouponDocument;

// Generic interface for LocalPatchProps, where T extends Document.
interface LocalPatchProps<T extends Document> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ import { CollectionKey, useCollection } from '../use-collection';
const mutationLogger = getLogger(['wcpos', 'mutations', 'document']);

type Document =
| OrderDocument
| ProductDocument
| CustomerDocument
| ProductVariationDocument
| CouponDocument;
OrderDocument | ProductDocument | CustomerDocument | ProductVariationDocument | CouponDocument;

interface Props {
collectionName: CollectionKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { useCurrentOrder } from '../pos/contexts/current-order';
export const useCurrentOrderCurrencyFormat = (options?: CurrencyFormatOptions) => {
const { currentOrder } = useCurrentOrder();
const currencySymbol = useObservableEagerState(currentOrder.currency_symbol$!) as
| string
| undefined;
string | undefined;
const { format } = useCurrencyFormat({ currencySymbol, ...options });

return {
Expand Down
3 changes: 1 addition & 2 deletions packages/core/src/screens/main/logs/cells/level.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ const variantMap: Record<string, string> = {
export function Level({ row, table }: CellContext<{ document: LogDocument }, 'level'>) {
const log = row.original.document;
const query = (table.options.meta as Record<string, unknown> | undefined)?.query as
| Query<any>
| undefined;
Query<any> | undefined;

const handlePress = React.useCallback(() => {
if (query) {
Expand Down
4 changes: 1 addition & 3 deletions packages/core/src/screens/main/orders/refund/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,7 @@ export function RefundOrderForm({ order }: Props) {
const taxRates = React.useContext(TaxRatesContext);
const storeDp = useObservableEagerState(store?.wc_price_decimals$) as number | undefined;
const taxDisplayCart = useObservableEagerState(store?.tax_display_cart$) as
| 'incl'
| 'excl'
| undefined;
'incl' | 'excl' | undefined;
const displayTax: 'incl' | 'excl' = taxDisplayCart === 'excl' ? 'excl' : 'incl';
const dp = resolvePriceNumDecimals({
contextDp: taxRates?.priceNumDecimals,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ import { useAvailablePrinterProfiles } from '../../settings/printer/use-availabl
import { useAppState } from '../../../../contexts/app-state';

export type PrinterSelection =
| { type: 'auto' }
| { type: 'system' }
| { type: 'manual'; printerId: string };
{ type: 'auto' } | { type: 'system' } | { type: 'manual'; printerId: string };

interface UseResolvedPrinterOptions {
template: TemplateInfo | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ export type CloudPrintResponse =
| CloudPrinterPayload[]
| {
printers?:
| CloudPrinterPayload[]
| CloudPrinterPayload
| Record<string, CloudPrinterPayload>
| null;
CloudPrinterPayload[] | CloudPrinterPayload | Record<string, CloudPrinterPayload> | null;
};

const SYSTEM_PRINTER: PrinterProfile = {
Expand Down
2 changes: 1 addition & 1 deletion packages/database/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"uuid": "^14.0.0"
},
"devDependencies": {
"@faker-js/faker": "^10.4.0",
"@faker-js/faker": "^10.5.0",
"@types/jest": "^30.0.0",
"@types/lodash": "^4.17.24",
"expo-sqlite": "~56.0.5",
Expand Down
3 changes: 1 addition & 2 deletions packages/database/src/migration/storage/index.native.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ describe('native storage migration configuration', () => {

getNativeOldStorage();
const sqliteStorageArgs = mockGetRxStorageSQLite.mock.calls[0]?.[0] as
| { sqliteBasics: { open(name: string): Promise<unknown> } }
| undefined;
{ sqliteBasics: { open(name: string): Promise<unknown> } } | undefined;

expect(sqliteStorageArgs).toBeDefined();
await sqliteStorageArgs!.sqliteBasics.open('wcposusers_v2');
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"eslint-config-expo": "^56.0.4",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.6",
"prettier": "^3.8.4",
"prettier": "^3.9.4",
"prettier-plugin-tailwindcss": "^0.8.0"
},
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/hooks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"@types/react": "^19.2.17",
"jest": "^30.4.2",
"react-native": "0.85.3",
"react-test-renderer": "19.2.3",
"react-test-renderer": "19.2.7",
"ts-jest": "^29.4.11"
}
}
2 changes: 1 addition & 1 deletion packages/printer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"@testing-library/react": "^16.3.2",
"jsdom": "^26.1.0",
"react-dom": "19.2.7",
"vitest": "^4.1.8"
"vitest": "^4.1.9"
},
"peerDependencies": {
"expo-print": ">=55.0.0",
Expand Down
Loading
Loading