انتقل إلى المحتوى الرئيسي

دليل اختبار الكاتب المسرحي: اختبارات E2E لتطبيقات Next.js

اكتب اختبارات شاملة وموثوقة لتطبيقات Next.js باستخدام Playwright. دليل كامل يغطي الإعداد وكائنات الصفحة واختبار المصادقة والانحدار المرئي وتكامل CI/CD.

E
ECOSIRE Research and Development Team
|5 مارس 20266 دقائق قراءة1.1k كلمات|

تكتشف الاختبارات الشاملة الأخطاء التي تغفلها اختبارات الوحدة - تدفقات المصادقة المعطلة، وفشل إرسال النماذج، وأخطاء التنقل، ومشكلات العرض عبر المستعرضات. أصبح Playwright، الذي أنشأته Microsoft، إطار عمل اختبار E2E الرائد بفضل دعمه للمتصفحات المتعددة، وإمكانيات الانتظار التلقائي، وأدوات تصحيح الأخطاء القوية.

**تكتشف الاختبارات الشاملة الأخطاء التي تغفلها اختبارات الوحدة - تدفقات المصادقة المعطلة، وفشل إرسال النماذج، وأخطاء التنقل، ومشكلات العرض عبر المستعرضات. ** أصبح Playwright، الذي أنشأته Microsoft، إطار عمل اختبار E2E الرائد بفضل دعمه للمتصفحات المتعددة، وإمكانيات الانتظار التلقائي، وأدوات تصحيح الأخطاء القوية.

الوجبات الرئيسية

  • يتم إجراء اختبارات الكاتب المسرحي عبر Chromium وFirefox وWebKit من مجموعة اختبار واحدة
  • يعمل الانتظار التلقائي على التخلص من الاختبارات غير المستقرة من خلال الانتظار حتى تصبح العناصر قابلة للتنفيذ قبل التفاعل
  • يمكن مشاركة حالة المصادقة عبر الاختبارات لتنفيذ أسرع
  • يوفر تكامل CI مع GitHub Actions اختبارًا آليًا لكل طلب سحب

إعداد المشروع

التثبيت

npm init playwright@latest

يؤدي هذا إلى تثبيت Playwright وإنشاء ملف تكوين وتنزيل ثنائيات المتصفح. بالنسبة لمشاريع Next.js، قم بتكوين خادم الويب ليبدأ تلقائيًا:

// playwright.config.ts
import { defineConfig } from "@playwright/test";

export default defineConfig({
  testDir: "./e2e",
  timeout: 30000,
  retries: process.env.CI ? 2 : 0,
  use: {
    baseURL: "http://localhost:3000",
    screenshot: "only-on-failure",
    trace: "on-first-retry",
  },
  webServer: {
    command: "npm run dev",
    port: 3000,
    reuseExistingServer: !process.env.CI,
  },
  projects: [
    { name: "chromium", use: { browserName: "chromium" } },
    { name: "firefox", use: { browserName: "firefox" } },
    { name: "webkit", use: { browserName: "webkit" } },
  ],
});

كتابة اختبارك الأول

اختبار الملاحة الأساسية

// e2e/navigation.spec.ts
import { test, expect } from "@playwright/test";

test("home page loads and displays title", async ({ page }) => {
  await page.goto("/");
  await expect(page).toHaveTitle(/ECOSIRE/);
  await expect(page.getByRole("heading", { level: 1 })).toBeVisible();
});

test("navigation to services page", async ({ page }) => {
  await page.goto("/");
  await page.getByRole("link", { name: "Services" }).click();
  await expect(page).toHaveURL(/services/);
  await expect(page.getByRole("heading", { name: /Services/ })).toBeVisible();
});

اختبار تقديم النموذج

test("contact form submission", async ({ page }) => {
  await page.goto("/contact");

  await page.getByLabel("Name").fill("Test User");
  await page.getByLabel("Email").fill("test@example.com");
  await page.getByLabel("Message").fill("This is a test message");
  await page.getByRole("button", { name: "Send" }).click();

  await expect(page.getByText("Message sent")).toBeVisible();
});

نمط كائن الصفحة

قم بتغليف تفاعلات الصفحة في كائنات الصفحة من أجل قابلية الصيانة:

// e2e/pages/login.page.ts
import { Page, expect } from "@playwright/test";

export class LoginPage {
  constructor(private page: Page) {}

  async goto() {
    await this.page.goto("/login");
  }

  async login(email: string, password: string) {
    await this.page.getByLabel("Email").fill(email);
    await this.page.getByLabel("Password").fill(password);
    await this.page.getByRole("button", { name: "Sign In" }).click();
  }

  async expectLoggedIn() {
    await expect(this.page).toHaveURL(/dashboard/);
  }

  async expectError(message: string) {
    await expect(this.page.getByText(message)).toBeVisible();
  }
}

استخدامها في الاختبارات:

test("successful login", async ({ page }) => {
  const loginPage = new LoginPage(page);
  await loginPage.goto();
  await loginPage.login("user@example.com", "password123");
  await loginPage.expectLoggedIn();
});

اختبار المصادقة

حالة المصادقة المشتركة

تجنب تسجيل الدخول قبل كل اختبار عن طريق حفظ حالة المصادقة:

// e2e/auth.setup.ts
import { test as setup } from "@playwright/test";

setup("authenticate", async ({ page }) => {
  await page.goto("/login");
  await page.getByLabel("Email").fill("admin@example.com");
  await page.getByLabel("Password").fill("admin-password");
  await page.getByRole("button", { name: "Sign In" }).click();
  await page.waitForURL("/dashboard");

  // Save authentication state
  await page.context().storageState({ path: ".auth/user.json" });
});

التكوين في playwright.config.ts:

projects: [
  { name: "setup", testMatch: /auth\.setup\.ts/ },
  {
    name: "authenticated",
    dependencies: ["setup"],
    use: { storageState: ".auth/user.json" },
  },
],

اختبار الانحدار البصري

اكتشف التغييرات المرئية غير المقصودة من خلال مقارنات لقطات الشاشة:

test("home page visual regression", async ({ page }) => {
  await page.goto("/");
  await expect(page).toHaveScreenshot("home-page.png", {
    maxDiffPixelRatio: 0.01,
  });
});

في أول تشغيل، يقوم Playwright بحفظ لقطات الشاشة الأساسية. تتم مقارنة عمليات التشغيل اللاحقة مع خطوط الأساس وتفشل إذا تجاوزت الاختلافات العتبة. قم بتحديث الخطوط الأساسية باستخدام --update-snapshots عندما تكون التغييرات مقصودة.


السخرية من واجهة برمجة التطبيقات

استجابات API وهمية للاختبار الحتمي:

test("displays products from API", async ({ page }) => {
  await page.route("/api/products", async (route) => {
    await route.fulfill({
      status: 200,
      contentType: "application/json",
      body: JSON.stringify([
        { id: 1, name: "Product A", price: 29.99 },
        { id: 2, name: "Product B", price: 49.99 },
      ]),
    });
  });

  await page.goto("/products");
  await expect(page.getByText("Product A")).toBeVisible();
  await expect(page.getByText("Product B")).toBeVisible();
});

تكامل CI/CD

إجراءات جيثب

name: E2E Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/

يتم تحميل تقارير الاختبار الفاشلة كعناصر لتصحيح الأخطاء، بما في ذلك لقطات الشاشة والتتبعات وتسجيلات الفيديو.


أدوات التصحيح

  • Playwright Inspector: قم بإجراء الاختبارات باستخدام علامة --debug للتنفيذ خطوة بخطوة
  • Trace Viewer: افتح عمليات التتبع لرؤية كل إجراء وطلب شبكة ولقطة DOM
  • Codegen: قم بتشغيل npx playwright codegen لتسجيل تفاعلات المتصفح وإنشاء كود الاختبار
  • VS Code Extension: تشغيل الاختبارات وتصحيح الأخطاء مباشرةً من VS Code باستخدام عناصر النقر لتحديد الموقع

أفضل الممارسات

  1. استخدم المحددات المستندة إلى الأدوار: تفضل getByRole، وgetByLabel، وgetByText على محددات CSS
  2. تجنب الانتظار المضمن: ثق في الانتظار التلقائي بدلاً من page.waitForTimeout()
  3. الاختبارات المعزولة: يجب أن يكون كل اختبار مستقلاً ولا يعتمد على اختبارات أخرى
  4. اختبار تدفقات المستخدم، وليس التنفيذ: ركز على ما يفعله المستخدمون، وليس على كيفية عمل التعليمات البرمجية
  5. الحفاظ على سرعة الاختبارات: استخدم اختصارات واجهة برمجة التطبيقات للإعداد (إنشاء بيانات اختبار عبر واجهة برمجة التطبيقات، وليس واجهة المستخدم)
  6. التشغيل في CI: يجب أن يجتاز كل طلب سحب اختبارات E2E قبل الدمج

الأسئلة المتداولة

س: كيف يمكن مقارنة الكاتب المسرحي بالسرو؟

يدعم Playwright متصفحات متعددة (Chromium وFirefox وWebKit) محليًا، بينما يستهدف Cypress متصفح Chromium بشكل أساسي. يعد الكاتب المسرحي أسرع في التنفيذ المتوازي ويتعامل مع علامات التبويب/النوافذ المتعددة. يتمتع Cypress بمنحنى تعليمي أسهل قليلًا وتصحيح أخطاء أقوى للسفر عبر الزمن.

س: كيف نتعامل مع الاختبارات غير المستقرة؟

الانتظار التلقائي للكاتب المسرحي يزيل معظم التقلبات. بالنسبة للمشكلات المتبقية: استخدم تأكيدات الويب أولاً (توقع محدد المواقع)، وتجنب اختبار السلوك المعتمد على التوقيت، وقم بتكوين عمليات إعادة المحاولة في CI. تساعد تقارير التتبع في تحديد السبب الجذري لحالات الفشل المتقطعة.

س: هل يجب علينا اختبار كل صفحة؟

التركيز على تدفقات المستخدم المهمة: المصادقة، وسير عمل الأعمال الأساسية، وعمليات إرسال النماذج، وتدفقات الدفع. لا تحتاج كل صفحة إلى اختبار E2E - استخدم اختبارات الوحدة والتكامل لتغطية مستوى المكونات.

س: ما المدة التي يجب أن تستغرقها اختبارات E2E؟

يجب أن تكتمل الاختبارات الفردية في أقل من 30 ثانية. يجب تشغيل المجموعة الكاملة لتطبيق متوسط ​​الحجم (50-100 اختبار) في أقل من 10 دقائق مع التنفيذ المتوازي.


ما هو التالي

يوفر اختبار E2E مع Playwright الثقة بأن تطبيقك يعمل بشكل صحيح من وجهة نظر المستخدم. ابدأ بالتدفقات المهمة وقم بتوسيع التغطية مع نمو تطبيقك.

اتصل بـ ECOSIRE لاختبار مساعدة التشغيل الآلي، أو استكشف خدمات تنفيذ Odoo لنشر تخطيط موارد المؤسسات (ERP) المضمون الجودة.


تم النشر بواسطة ECOSIRE - مساعدة الشركات على التوسع باستخدام حلول برمجيات المؤسسات.

E

بقلم

ECOSIRE Team

Technical Writing

The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.

ECOSIRE

قم بتنمية أعمالك مع ECOSIRE

حلول المؤسسات عبر تخطيط موارد المؤسسات (ERP) والتجارة الإلكترونية والذكاء الاصطناعي والتحليلات والأتمتة.

مقالات ذات صلة

accounts-payable

عائد الاستثمار لأتمتة الحسابات الدائنة: الأرقام الحقيقية وراء خفض تكاليف الفواتير من 12 دولارًا إلى 2 دولار (2026)

تؤدي أتمتة الحسابات الدائنة إلى خفض معالجة الفواتير من 12 إلى 15 دولارًا إلى أقل من 3 دولارات لكل منها. الرياضيات الكاملة لعائد الاستثمار لعام 2026: الاسترداد حسب الحجم، ومصادر الادخار، والحدود.

6 يونيو 2026
automation

25 نموذجًا لأتمتة العمليات التجارية التي تعمل فعليًا في عام 2026 (من فريق يديرها في الإنتاج)

25 مثالًا حقيقيًا لأتمتة عمليات الأعمال عبر التمويل والمبيعات والدعم والعمليات - مع ملاحظات صادقة حول أفضل ما يفعله وكلاء الذكاء الاصطناعي وأتمتة العمليات الروبوتية وسير العمل.

6 يونيو 2026
gohighlevel

موظف GoHighLevel AI في عام 2026: ماذا يفعل، وتكلفته، ومتى يتم استخدامه

شرح موظف GoHighLevel AI لعام 2026: قدرات الذكاء الاصطناعي الصوتي، والذكاء الاصطناعي للمحادثة، والذكاء الاصطناعي للمحتوى، وتسعير السعر الثابت مقابل الاستخدام، والحدود، ومتى يتم الدفع.

6 يونيو 2026