Skip to content

Commit 1bf2a1b

Browse files
feat(medium): Fix Google Doc parser regression and address PR feedback (#9070)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: arii <342438+arii@users.noreply.github.com>
1 parent 7a2d8bb commit 1bf2a1b

6 files changed

Lines changed: 46 additions & 36 deletions

File tree

app/api/workout/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export async function GET(request: Request) {
1818
const exportUrl = `https://docs.google.com/document/d/${docId}/export?format=html`
1919

2020
const response = await fetch(exportUrl, {
21-
next: { revalidate: 60 }, // Cache to avoid hitting Google limits
21+
next: { revalidate: 60 },
2222
})
2323

2424
if (!response.ok) {

app/client/connect/page.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@ import { HrmInputMessage } from '@/types/websocket'
2424
import logger from '@/utils/logger'
2525

2626
export default function ConnectPage() {
27-
const [isReady, setIsReady] = useState(false)
28-
useEffect(() => {
29-
const timer = setTimeout(() => setIsReady(true), 0)
30-
return () => clearTimeout(timer)
31-
}, [])
32-
3327
const [userSettings, setUserSettings] = useUserSettings()
3428
const { userName, userAge, userWeight, gender, unitSystem } = userSettings
3529

components/WorkoutTableHeader.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export default function WorkoutTableHeader({
3434
const fetchData = async () => {
3535
try {
3636
setLoading(true)
37-
setError(null) // Reset error on re-fetch
37+
setError(null)
3838
const res = await fetch(`/api/workout?docId=${docId}`)
3939
if (!res.ok) throw new Error('Failed to load workout data')
4040
const json = await res.json()
@@ -87,7 +87,7 @@ export default function WorkoutTableHeader({
8787
<TableHead>
8888
<TableRow sx={{ backgroundColor: 'action.hover' }}>
8989
{data.headers.map((header, index) => (
90-
<TableCell key={index} sx={{ fontWeight: 'bold' }}>
90+
<TableCell key={index} sx={{ fontWeight: 'bold' }} scope="col">
9191
{header}
9292
</TableCell>
9393
))}

services/googleDocParser.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export const parseGoogleDocTable = (html: string): WorkoutTableDto => {
2626
firstRow.find('td, th').each((_colIndex, cellElement) => {
2727
const text = $(cellElement)
2828
.text()
29+
.replace(/\u00A0/g, ' ')
2930
.replace(/\r?\n|\r/g, ' ')
3031
.trim()
3132
headers.push(text)

tests/playwright/lib/waits.ts

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -47,49 +47,33 @@ export async function waitForPageReady(
4747
): Promise<void> {
4848
const { timeout = WAIT_TIMEOUTS.TEST_READY } = options
4949

50-
<<<<<<< HEAD
51-
// Wait for fonts to be loaded
52-
=======
5350
// Wait for fonts to be ready
54-
>>>>>>> origin/leader
5551
await page.evaluate(async () => {
5652
await document.fonts.ready
5753
})
5854

55+
// Wait for actual content to be present first (Fail-Fast check)
56+
await page.waitForSelector('main, [data-testid="dashboard"], [role="main"]', {
57+
state: 'visible',
58+
timeout,
59+
})
60+
5961
// Wait for loading skeletons to disappear
60-
<<<<<<< HEAD
62+
// We use hidden state to ensure they are either removed or invisible.
6163
// NOTE: We wrap this in a try-catch to prevent timeouts from failing the entire test.
62-
// In some CI environments, dynamic content loading (like Spotify or Google Docs)
63-
// or WebSocket connection states might cause skeletons to persist longer than expected.
64-
// Proceeding allows visual regression tests to capture the state (even if loading)
65-
// rather than failing with a timeout error.
64+
// If skeletons persist (e.g. infinite loading or bug), we want VRT to capture that state
65+
// rather than crashing with a generic TimeoutError.
6666
try {
6767
await page.waitForSelector('.MuiSkeleton-root', {
68-
state: 'detached',
68+
state: 'hidden',
6969
timeout,
7070
})
7171
} catch (error) {
7272
console.warn(
73-
`[waitForPageReady] Skeletons did not detach within ${timeout}ms. Proceeding anyway.`,
73+
`[waitForPageReady] Skeletons did not disappear within ${timeout}ms. Proceeding to snapshot/test.`,
7474
error
7575
)
7676
}
77-
=======
78-
await page
79-
.waitForSelector('.MuiSkeleton-root', {
80-
state: 'hidden',
81-
timeout,
82-
})
83-
.catch(() => {
84-
// Ignore errors if skeletons are not found (already hidden/removed)
85-
})
86-
87-
// Wait for actual content to be present
88-
await page.waitForSelector('main, [data-testid="dashboard"], [role="main"]', {
89-
state: 'visible',
90-
timeout,
91-
})
92-
>>>>>>> origin/leader
9377
}
9478

9579
/**
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/** @jest-environment jsdom */
2+
import { render, screen, fireEvent } from '@testing-library/react'
3+
import RefreshIconButton from '../../../components/RefreshIconButton'
4+
5+
describe('RefreshIconButton', () => {
6+
it('renders correctly', () => {
7+
render(<RefreshIconButton onClick={() => {}} />)
8+
const button = screen.getByRole('button')
9+
expect(button).toBeInTheDocument()
10+
})
11+
12+
it('calls onClick when clicked', () => {
13+
const handleClick = jest.fn()
14+
render(<RefreshIconButton onClick={handleClick} />)
15+
const button = screen.getByRole('button')
16+
fireEvent.click(button)
17+
expect(handleClick).toHaveBeenCalledTimes(1)
18+
})
19+
20+
it('passes other props to IconButton', () => {
21+
render(<RefreshIconButton onClick={() => {}} aria-label="custom label" />)
22+
const button = screen.getByRole('button', { name: 'custom label' })
23+
expect(button).toBeInTheDocument()
24+
})
25+
26+
it('renders the refresh icon', () => {
27+
render(<RefreshIconButton onClick={() => {}} />)
28+
const button = screen.getByRole('button')
29+
expect(button.querySelector('svg')).toBeInTheDocument()
30+
})
31+
})

0 commit comments

Comments
 (0)