-
Notifications
You must be signed in to change notification settings - Fork 57
feature: add solution on daily 11/13 KT #279
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughA new Playwright test case for a Pikachu game has been added to the Changes
Sequence DiagramsequenceDiagram
participant Test as Playwright Test
participant Game as Pikachu Game
participant Dialog as Win Dialog
Test->>Game: Navigate to Game URL
Test->>Game: Enter Player Name
Test->>Game: Click Start Button
loop Match Pikachu Pairs
Test->>Game: Click First Pikachu
Test->>Game: Click Matching Pikachu
Game-->>Dialog: Trigger Win Dialog
end
Test->>Dialog: Accept Win Dialog
Possibly related PRs
Suggested reviewers
Poem
Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
test('pikachu', async ({page}) => { | ||
await page.goto('https://material.playwrightvn.com/games/002-pikachu.html'); | ||
await page.fill(`//input[@id='playerName']`,`khanh5923_13`); | ||
await page.click(`//button[@onclick='startGame()']`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve test maintainability and reliability
- Move configuration to test fixtures or environment variables:
const TEST_CONFIG = {
gameUrl: 'https://material.playwrightvn.com/games/002-pikachu.html',
playerName: 'khanh5923_13'
};
- Replace XPath selectors with more maintainable data-testid or CSS selectors:
-await page.fill(`//input[@id='playerName']`,`khanh5923_13`);
-await page.click(`//button[@onclick='startGame()']`);
+await page.fill('#playerName', TEST_CONFIG.playerName);
+await page.getByRole('button', { name: 'Start Game' }).click();
const maxNumberOfPikachu = await page.locator(`//div[@id='grid']//div[@class="outer"]`).count(); | ||
page.on('dialog', async (dialog) => { | ||
expect(dialog.message()).toBe('Bạn đã thắng cuộc!'); | ||
await dialog.accept(); | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add proper game initialization checks and error handling
- Move dialog handler setup before game start to catch all possible dialogs
- Add error handling for unexpected dialogs
- Verify game grid is properly loaded
// Add before game start
await page.waitForSelector('#grid', { state: 'visible' });
page.on('dialog', async (dialog) => {
const message = dialog.message();
if (message === 'Bạn đã thắng cuộc!') {
await dialog.accept();
} else {
console.warn(`Unexpected dialog: ${message}`);
await dialog.dismiss();
}
});
for (let i = 1; i <= maxNumberOfPikachu/2; i++) { | ||
const firstPikachu = page.locator(`//div[@id='grid']//div[@class="outer"][1]`); | ||
const textPikachuSelected = await firstPikachu.textContent(); | ||
await firstPikachu.click(); | ||
await page.click(`//div[@id='grid']//div[@class="outer" and text()='${textPikachuSelected}']`); | ||
await page.waitForTimeout(1000); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve game interaction reliability
The current implementation has several potential issues:
- Always clicking the first element might not work if matches are removed
- Hardcoded waits can cause test flakiness
- No verification that matches were successful
Consider this more robust approach:
async function findAndClickMatch(page: Page) {
const grid = page.locator('#grid');
const elements = await grid.locator('.outer').all();
for (const element of elements) {
if (await element.isVisible()) {
const text = await element.textContent();
await element.click();
// Wait for highlight animation
await page.waitForTimeout(100);
// Find and click matching element
const matches = await grid.locator(`.outer:visible:text("${text}")`).all();
if (matches.length > 1) {
await matches[1].click();
// Wait for match animation to complete
await page.waitForResponse(response =>
response.url().includes('match-success')
);
}
break;
}
}
}
// In the test
while (await page.locator('.outer:visible').count() > 0) {
await findAndClickMatch(page);
}
test('pikachu', async ({page}) => { | ||
await page.goto('https://material.playwrightvn.com/games/002-pikachu.html'); | ||
await page.fill(`//input[@id='playerName']`,`khanh5923_13`); | ||
await page.click(`//button[@onclick='startGame()']`); | ||
const maxNumberOfPikachu = await page.locator(`//div[@id='grid']//div[@class="outer"]`).count(); | ||
page.on('dialog', async (dialog) => { | ||
expect(dialog.message()).toBe('Bạn đã thắng cuộc!'); | ||
await dialog.accept(); | ||
}) | ||
for (let i = 1; i <= maxNumberOfPikachu/2; i++) { | ||
const firstPikachu = page.locator(`//div[@id='grid']//div[@class="outer"][1]`); | ||
const textPikachuSelected = await firstPikachu.textContent(); | ||
await firstPikachu.click(); | ||
await page.click(`//div[@id='grid']//div[@class="outer" and text()='${textPikachuSelected}']`); | ||
await page.waitForTimeout(1000); | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Add test robustness improvements
Consider adding these test best practices:
- Add retry logic for flaky operations
- Capture screenshots on failure
- Add proper test cleanup
test('pikachu', async ({ page }) => {
test.info().annotations.push({
type: 'test',
description: 'Verify Pikachu game completion'
});
try {
// ... existing test code ...
} catch (error) {
await page.screenshot({ path: 'pikachu-game-error.png' });
throw error;
} finally {
// Cleanup: Close any open dialogs, reset game state
await page.evaluate(() => window.localStorage.clear());
}
});
import {test, expect} from '@playwright/test'; | ||
|
||
test.setTimeout(60000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Consider optimizing test configuration
- The 60-second timeout might be excessive for this test. Consider reducing it to a more reasonable duration (e.g., 30 seconds) and using explicit waits where needed.
- Add TypeScript types for better code completion and type safety:
-import {test, expect} from '@playwright/test';
+import type { Page } from '@playwright/test';
+import { test, expect } from '@playwright/test';
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import {test, expect} from '@playwright/test'; | |
test.setTimeout(60000); | |
import type { Page } from '@playwright/test'; | |
import { test, expect } from '@playwright/test'; | |
test.setTimeout(60000); |
Hi anh/ chị, mọi người xem giúp em bài này với ạ.
Summary by CodeRabbit