Skip to content

Commit fcd0aae

Browse files
committed
debug: forward all browser logs and add MutationObserver to catch section-a hide
Previous CI debug run showed PRE_SWIPE section-a visible and POST_SWIPE hidden, but no [SwipeBack*] browser-console logs were forwarded. Forward every browser console event via page.on('console') and install a MutationObserver on #section-a to dump the exact stack that mutates class/style/aria-hidden during the gesture.
1 parent a550b61 commit fcd0aae

2 files changed

Lines changed: 72 additions & 5 deletions

File tree

packages/react-router/src/ReactRouter/StackManager.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,19 @@ export class StackManager extends React.PureComponent<StackManagerProps> {
11171117
let leavingViewItem = viewItems.leavingViewItem;
11181118
let shouldUnmountLeavingViewItem = this.shouldUnmountLeavingView(routeInfo, enteringViewItem, leavingViewItem);
11191119

1120+
if (this.id === 'modal-aria-hidden-root' || this.id === 'section-a' || this.id === 'section-b') {
1121+
// eslint-disable-next-line no-console
1122+
console.log('[HPT:entry]', JSON.stringify({
1123+
outletId: this.id,
1124+
pathname: routeInfo.pathname,
1125+
routeAction: routeInfo.routeAction,
1126+
routeDirection: routeInfo.routeDirection,
1127+
enteringViewPath: enteringViewItem?.reactElement?.props?.path,
1128+
leavingViewPath: leavingViewItem?.reactElement?.props?.path,
1129+
shouldUnmountLeavingViewItem,
1130+
}));
1131+
}
1132+
11201133
// Get parent path for nested outlets
11211134
const parentPath = this.getParentPath();
11221135

@@ -1507,6 +1520,25 @@ export class StackManager extends React.PureComponent<StackManagerProps> {
15071520
) {
15081521
const myGeneration = ++this.transitionGeneration;
15091522

1523+
if (this.id === 'modal-aria-hidden-root' || this.id === 'section-a' || this.id === 'section-b') {
1524+
// eslint-disable-next-line no-console
1525+
console.log('[TP:entry]', JSON.stringify({
1526+
outletId: this.id,
1527+
direction,
1528+
progressAnimation,
1529+
skipAnimation,
1530+
enteringId: enteringViewItem?.id,
1531+
enteringPath: enteringViewItem?.reactElement?.props?.path,
1532+
enteringPageElementId: enteringViewItem?.ionPageElement?.id,
1533+
leavingId: leavingViewItem?.id,
1534+
leavingPath: leavingViewItem?.reactElement?.props?.path,
1535+
leavingPageElementId: leavingViewItem?.ionPageElement?.id,
1536+
routeAction: routeInfo.routeAction,
1537+
routeDirection: routeInfo.routeDirection,
1538+
routePathname: routeInfo.pathname,
1539+
}));
1540+
}
1541+
15101542
const runCommit = async (enteringEl: HTMLElement, leavingEl?: HTMLElement) => {
15111543
const skipTransition = this.skipTransition;
15121544

packages/react-router/test/base/tests/e2e/playwright/ionpage-swipe-back.spec.ts

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@ const IOS_MODE = 'ionic:mode=ios';
2424
test.describe('ionPage outlet swipe-to-go-back', () => {
2525
test('section-a content should be visible during swipe-back from section-b', async ({ page }) => {
2626
page.on('console', (msg) => {
27-
const text = msg.text();
28-
if (text.startsWith('[SwipeBack') || text.startsWith('[HideIonPageElement]')) {
29-
// eslint-disable-next-line no-console
30-
console.log('PAGE:', text);
31-
}
27+
// eslint-disable-next-line no-console
28+
console.log('BROWSER[' + msg.type() + ']:', msg.text());
29+
});
30+
page.on('pageerror', (err) => {
31+
// eslint-disable-next-line no-console
32+
console.log('PAGEERROR:', err.message);
3233
});
3334

3435
// Navigate to modal-aria-hidden test page (has sibling ionPage outlets)
@@ -41,6 +42,36 @@ test.describe('ionPage outlet swipe-to-go-back', () => {
4142
await page.locator('#navigateToB').click();
4243
await ionPageVisible(page, 'modal-page-b');
4344

45+
// Install a MutationObserver on section-a to catch anyone adding ion-page-hidden
46+
await page.evaluate(() => {
47+
const target = document.querySelector('#section-a');
48+
if (!target) {
49+
// eslint-disable-next-line no-console
50+
console.log('[MO-install] #section-a not found!');
51+
return;
52+
}
53+
const obs = new MutationObserver((mutations) => {
54+
for (const m of mutations) {
55+
if (m.type === 'attributes' && (m.attributeName === 'class' || m.attributeName === 'style' || m.attributeName === 'aria-hidden')) {
56+
const el = m.target as HTMLElement;
57+
// eslint-disable-next-line no-console
58+
console.log('[MO-change]', JSON.stringify({
59+
attr: m.attributeName,
60+
oldValue: m.oldValue,
61+
newClass: el.className,
62+
newStyle: el.getAttribute('style'),
63+
newAriaHidden: el.getAttribute('aria-hidden'),
64+
stack: new Error().stack?.split('\n').slice(1, 8).map((s) => s.trim()),
65+
}));
66+
}
67+
}
68+
});
69+
obs.observe(target, { attributes: true, attributeOldValue: true });
70+
(window as any).__sectionAObserver = obs;
71+
// eslint-disable-next-line no-console
72+
console.log('[MO-install] observer attached to #section-a');
73+
});
74+
4475
// Pre-swipe: dump section-a state
4576
const preSwipe = await page.locator('#section-a').evaluate((el: HTMLElement) => ({
4677
inlineDisplay: el.style.display,
@@ -76,6 +107,10 @@ test.describe('ionPage outlet swipe-to-go-back', () => {
76107
// eslint-disable-next-line no-console
77108
console.log('POST_SWIPE section-a:', JSON.stringify(postSwipe));
78109

110+
// Also dump current URL to see if navigation fired
111+
// eslint-disable-next-line no-console
112+
console.log('POST_SWIPE url:', page.url());
113+
79114
// Mid-swipe: section-a should be visible (not display:none) with its child content
80115
const sectionA = page.locator('#section-a');
81116
const computedDisplay = await sectionA.evaluate((el: HTMLElement) => getComputedStyle(el).display);

0 commit comments

Comments
 (0)