ReferenceError: document ไม่ได้ถูกกำหนด ข้อผิดพลาด Typescript ใน Playwright
ความคิดคือฉันกำลังพยายามดึงหัวข้อ HTML ทั้งหมด (h1 h2 h3 h4 h5 h6) และทดสอบว่าพวกมันเรียงตามลำดับที่เป็นมิตรกับ SEO หรือไม่ ถ้าฉันพยายามรันมัน ฉันจะได้ข้อผิดพลาด ReferenceError: document is not defined ใน Typescript บน Playwright
async assertHeadingsOrder2() {
// eslint-disable-next-line @typescript-eslint/require-await
await test.step('Test html header structure for catalog page', async () => {
// Get all the heading tags (h1, h2, h3, h4, h5, h6) in the document
const headingTags = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
// Define a function to test the hierarchy
function testHeadingHierarchy() {
const hierarchy = [];
headingTags.forEach(heading => {
const tagName = heading.tagName.toLowerCase(); // Get the tag name (e.g., "h1", "h2")
const level = parseInt(tagName.charAt(1), 10); // Extract the numeric level from the tag name
// Check if the hierarchy is valid
if (level > hierarchy.length + 1) {
console.error(`Invalid hierarchy: ${tagName} is not in the correct order.`);
}
// Update the hierarchy array with the current level
hierarchy[level - 1] = tagName;
});
console.log('Heading hierarchy is valid:', hierarchy.join(' > '));
}
// Call the function to test the hierarchy
testHeadingHierarchy();
});
}
คำตอบ #1
Playwright จะไม่ทำให้ document ใช้งานได้โดยอัตโนมัติใน Node แต่จะให้คุณใช้วัตถุ browser และ page ที่มี API ที่ครอบคลุมสำหรับจัดการเว็บไซต์
คุณสามารถใช้ page.evaluate() เพื่อรันโค้ดในเบราว์เซอร์และเข้าถึง document แต่โดยปกติแล้ว คุณจะเลือกองค์ประกอบด้วย API สำหรับตัวระบุตำแหน่ง (locators) บนวัตถุ page
ตัวเลือก CSS ของคุณควรเป็น "h1, h2, h3, h4, h5, h6" แทนที่จะเป็น "h1 h2 h3 h4 h5 h6" แบบแรกใช้เครื่องหมายจุลภาคสำหรับตรรกะ "หรือ" ขณะที่แบบหลังจะเลือก <h6> ที่ซ้อนอยู่ภายในหัวข้ออื่นทั้งหมด
นี่คือตัวอย่าง:
import {expect, test} from "@playwright/test"; // ^1.39.0
const failMsg = (prev, curr) =>
`h${curr} was more than one level deeper than previous header h${prev}`;
test("detects a skipped heading", async ({page}) => {
test.fail(); // expect this test to fail
const html = `<!DOCTYPE html><html><body>
<h1>1</h1>
<h2>2</h2>
<h4>4</h4>
</body></html>`;
await page.setContent(html); // replace with page.goto("<Your URL>"); when you're working with a real site
const headers = await page
.locator("h1, h2, h3, h4, h5, h6")
.evaluateAll(els => els.map(el => +el.tagName.slice(1)));
for (let i = 1; i < headers.length; i++) {
expect(
headers[i] - headers[i-1],
failMsg(headers[i-1], headers[i])
).toBeLessThan(2);
}
});
test("handles a valid structure", async ({page}) => {
const html = `<!DOCTYPE html><html><body>
<h1>1</h1>
<h2>2</h2>
<h3>3</h3>
<h4>4</h4>
<h4>4</h4>
<h2>2</h2> <!-- it's OK to skip back, just not forward -->
<h3>3</h3>
</body></html>`;
await page.setContent(html);
const headers = await page
.locator("h1, h2, h3, h4, h5, h6")
.evaluateAll(els => els.map(el => +el.tagName.slice(1)));
for (let i = 1; i < headers.length; i++) {
expect(
headers[i] - headers[i-1],
failMsg(headers[i-1], headers[i])
).toBeLessThan(2);
}
});
test("handles a valid structure on a real site", async ({page}) => {
await page.goto("https://playwright.dev/docs/test-assertions");
const headers = await page
.locator("h1, h2, h3, h4, h5, h6")
.evaluateAll(els => els.map(el => +el.tagName.slice(1)));
for (let i = 1; i < headers.length; i++) {
expect(
headers[i] - headers[i-1],
failMsg(headers[i-1], headers[i])
).toBeLessThan(2);
}
});
สำหรับการทดสอบจริงของคุณ คุณน่าจะใช้ page.goto() แทน page.setContent ซึ่งในที่นี้ใช้เพื่อช่วยแสดงตรรกะของการอ้างอิงได้อย่างง่ายๆ
คุณอาจต้องการใช้ตัวแมตช์แบบกำหนดเองเพื่อช่วยสรุปข้อความเทมเพลตข้อผิดพลาดที่ยาวและลูปที่ชัดเจน และ/หรือเขียนฟังก์ชันช่วยเหลือเพื่อดึงหัวข้อ
นอกจากนี้ ข้อสันนิษฐานนี้ไม่ได้รออัตโนมัติ แต่ฉันสมมติว่าหัวข้อคงโอเคที่จะดึงมากหรือน้อยได้ในครั้งเดียว หากสมมติฐานนั้นไม่เป็นความจริง ลองใช้ poll หรือ toPass
