Google Antigravity Directory

The #1 directory for Google Antigravity prompts, rules, workflows & MCP servers. Optimized for Gemini 3 agentic development.

Resources

PromptsMCP ServersAntigravity RulesGEMINI.md GuideBest Practices

Company

Submit PromptAntigravityAI.directory

Popular Prompts

Next.js 14 App RouterReact TypeScriptTypeScript AdvancedFastAPI GuideDocker Best Practices

Legal

Privacy PolicyTerms of ServiceContact Us
Featured on FazierVerified on Verified ToolsFeatured on WayfindioAntigravity AI - Featured on Startup FameFeatured on Wired BusinessFeatured on Twelve ToolsListed on Turbo0Featured on findly.toolsFeatured on Aura++That App ShowFeatured on FazierVerified on Verified ToolsFeatured on WayfindioAntigravity AI - Featured on Startup FameFeatured on Wired BusinessFeatured on Twelve ToolsListed on Turbo0Featured on findly.toolsFeatured on Aura++That App Show

© 2026 Antigravity AI Directory. All rights reserved.

The #1 directory for Google Antigravity IDE

This website is not affiliated with, endorsed by, or associated with Google LLC. "Google" and "Gemini" are trademarks of Google LLC.

Antigravity AI Directory
PromptsMCPBest PracticesUse CasesLearn
Home
Prompts
Playwright E2E Testing

Playwright E2E Testing

Write reliable end-to-end tests with Playwright for cross-browser testing and automation.

PlaywrightTestingE2EAutomation
by Community
⭐0Stars
👁️36Views
📋11Copies
.antigravity
# Playwright E2E Testing for Google Antigravity

Master end-to-end testing with Playwright in your Google Antigravity projects. This guide covers test architecture, page objects, visual testing, and CI/CD integration for reliable browser automation.

## Playwright Configuration

Set up a comprehensive test environment:

```typescript
// playwright.config.ts
import { defineConfig, devices } from "@playwright/test";

export default defineConfig({
  testDir: "./e2e",
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: [
    ["html", { open: "never" }],
    ["json", { outputFile: "test-results/results.json" }],
    ["junit", { outputFile: "test-results/junit.xml" }],
  ],
  
  use: {
    baseURL: process.env.BASE_URL || "http://localhost:3000",
    trace: "on-first-retry",
    screenshot: "only-on-failure",
    video: "retain-on-failure",
    actionTimeout: 15000,
    navigationTimeout: 30000,
  },
  
  projects: [
    {
      name: "chromium",
      use: { ...devices["Desktop Chrome"] },
    },
    {
      name: "firefox",
      use: { ...devices["Desktop Firefox"] },
    },
    {
      name: "webkit",
      use: { ...devices["Desktop Safari"] },
    },
    {
      name: "mobile-chrome",
      use: { ...devices["Pixel 5"] },
    },
    {
      name: "mobile-safari",
      use: { ...devices["iPhone 12"] },
    },
  ],
  
  webServer: {
    command: "npm run dev",
    url: "http://localhost:3000",
    reuseExistingServer: !process.env.CI,
    timeout: 120000,
  },
});
```

## Page Object Model

Create maintainable page objects:

```typescript
// e2e/pages/BasePage.ts
import { Page, Locator, expect } from "@playwright/test";

export abstract class BasePage {
  readonly page: Page;
  readonly url: string;
  
  constructor(page: Page, url: string) {
    this.page = page;
    this.url = url;
  }
  
  async goto(): Promise<void> {
    await this.page.goto(this.url);
    await this.waitForPageLoad();
  }
  
  async waitForPageLoad(): Promise<void> {
    await this.page.waitForLoadState("networkidle");
  }
  
  async getTitle(): Promise<string> {
    return this.page.title();
  }
  
  async screenshot(name: string): Promise<void> {
    await this.page.screenshot({ path: `screenshots/${name}.png` });
  }
}

// e2e/pages/LoginPage.ts
import { Page, Locator, expect } from "@playwright/test";
import { BasePage } from "./BasePage";

export class LoginPage extends BasePage {
  readonly emailInput: Locator;
  readonly passwordInput: Locator;
  readonly submitButton: Locator;
  readonly errorMessage: Locator;
  readonly forgotPasswordLink: Locator;
  
  constructor(page: Page) {
    super(page, "/login");
    
    this.emailInput = page.getByLabel("Email");
    this.passwordInput = page.getByLabel("Password");
    this.submitButton = page.getByRole("button", { name: "Sign In" });
    this.errorMessage = page.getByRole("alert");
    this.forgotPasswordLink = page.getByRole("link", { name: "Forgot password?" });
  }
  
  async login(email: string, password: string): Promise<void> {
    await this.emailInput.fill(email);
    await this.passwordInput.fill(password);
    await this.submitButton.click();
  }
  
  async expectError(message: string): Promise<void> {
    await expect(this.errorMessage).toContainText(message);
  }
  
  async expectSuccessfulLogin(): Promise<void> {
    await expect(this.page).toHaveURL("/dashboard");
  }
}

// e2e/pages/DashboardPage.ts
import { Page, Locator, expect } from "@playwright/test";
import { BasePage } from "./BasePage";

export class DashboardPage extends BasePage {
  readonly welcomeMessage: Locator;
  readonly userMenu: Locator;
  readonly logoutButton: Locator;
  readonly statsCards: Locator;
  readonly recentActivity: Locator;
  
  constructor(page: Page) {
    super(page, "/dashboard");
    
    this.welcomeMessage = page.getByTestId("welcome-message");
    this.userMenu = page.getByTestId("user-menu");
    this.logoutButton = page.getByRole("button", { name: "Logout" });
    this.statsCards = page.getByTestId("stats-card");
    this.recentActivity = page.getByTestId("recent-activity");
  }
  
  async logout(): Promise<void> {
    await this.userMenu.click();
    await this.logoutButton.click();
    await expect(this.page).toHaveURL("/login");
  }
  
  async getStatsCount(): Promise<number> {
    return this.statsCards.count();
  }
}
```

## Test Fixtures and Utilities

Create reusable test utilities:

```typescript
// e2e/fixtures/auth.fixture.ts
import { test as base, Page } from "@playwright/test";
import { LoginPage } from "../pages/LoginPage";
import { DashboardPage } from "../pages/DashboardPage";

type AuthFixtures = {
  loginPage: LoginPage;
  dashboardPage: DashboardPage;
  authenticatedPage: Page;
};

export const test = base.extend<AuthFixtures>({
  loginPage: async ({ page }, use) => {
    const loginPage = new LoginPage(page);
    await use(loginPage);
  },
  
  dashboardPage: async ({ page }, use) => {
    const dashboardPage = new DashboardPage(page);
    await use(dashboardPage);
  },
  
  authenticatedPage: async ({ page, context }, use) => {
    // Set up authentication state
    await context.addCookies([
      {
        name: "auth_token",
        value: process.env.TEST_AUTH_TOKEN!,
        domain: "localhost",
        path: "/",
      },
    ]);
    
    await page.goto("/dashboard");
    await use(page);
  },
});

export { expect } from "@playwright/test";
```

## Writing Comprehensive Tests

Create thorough test suites:

```typescript
// e2e/tests/auth.spec.ts
import { test, expect } from "../fixtures/auth.fixture";

test.describe("Authentication Flow", () => {
  test.beforeEach(async ({ loginPage }) => {
    await loginPage.goto();
  });
  
  test("should display login form", async ({ loginPage }) => {
    await expect(loginPage.emailInput).toBeVisible();
    await expect(loginPage.passwordInput).toBeVisible();
    await expect(loginPage.submitButton).toBeVisible();
  });
  
  test("should show error for invalid credentials", async ({ loginPage }) => {
    await loginPage.login("invalid@example.com", "wrongpassword");
    await loginPage.expectError("Invalid email or password");
  });
  
  test("should login successfully with valid credentials", async ({ loginPage }) => {
    await loginPage.login("test@example.com", "password123");
    await loginPage.expectSuccessfulLogin();
  });
  
  test("should validate required fields", async ({ loginPage }) => {
    await loginPage.submitButton.click();
    
    await expect(loginPage.page.getByText("Email is required")).toBeVisible();
    await expect(loginPage.page.getByText("Password is required")).toBeVisible();
  });
  
  test("should navigate to forgot password", async ({ loginPage }) => {
    await loginPage.forgotPasswordLink.click();
    await expect(loginPage.page).toHaveURL("/forgot-password");
  });
});

test.describe("Dashboard", () => {
  test("should display user dashboard after login", async ({ authenticatedPage }) => {
    const dashboardPage = new DashboardPage(authenticatedPage);
    
    await expect(dashboardPage.welcomeMessage).toBeVisible();
    await expect(dashboardPage.statsCards.first()).toBeVisible();
  });
  
  test("should logout successfully", async ({ authenticatedPage }) => {
    const dashboardPage = new DashboardPage(authenticatedPage);
    await dashboardPage.logout();
    
    await expect(authenticatedPage).toHaveURL("/login");
  });
});
```

## Visual Regression Testing

Implement screenshot comparisons:

```typescript
// e2e/tests/visual.spec.ts
import { test, expect } from "@playwright/test";

test.describe("Visual Regression", () => {
  test("homepage matches snapshot", async ({ page }) => {
    await page.goto("/");
    await page.waitForLoadState("networkidle");
    
    await expect(page).toHaveScreenshot("homepage.png", {
      fullPage: true,
      maxDiffPixelRatio: 0.01,
    });
  });
  
  test("login page matches snapshot", async ({ page }) => {
    await page.goto("/login");
    
    await expect(page).toHaveScreenshot("login-page.png", {
      mask: [page.locator("[data-testid='dynamic-content']")],
    });
  });
  
  test("responsive design - mobile", async ({ page }) => {
    await page.setViewportSize({ width: 375, height: 667 });
    await page.goto("/");
    
    await expect(page).toHaveScreenshot("homepage-mobile.png");
  });
});
```

## API Mocking

Mock API responses for isolated testing:

```typescript
// e2e/tests/api-mock.spec.ts
import { test, expect } from "@playwright/test";

test.describe("API Mocking", () => {
  test("should handle API errors gracefully", async ({ page }) => {
    await page.route("**/api/users", (route) => {
      route.fulfill({
        status: 500,
        contentType: "application/json",
        body: JSON.stringify({ error: "Internal server error" }),
      });
    });
    
    await page.goto("/users");
    await expect(page.getByText("Something went wrong")).toBeVisible();
  });
  
  test("should display mocked data", async ({ page }) => {
    await page.route("**/api/products", (route) => {
      route.fulfill({
        status: 200,
        contentType: "application/json",
        body: JSON.stringify({
          products: [
            { id: 1, name: "Test Product", price: 99.99 },
          ],
        }),
      });
    });
    
    await page.goto("/products");
    await expect(page.getByText("Test Product")).toBeVisible();
  });
});
```

Google Antigravity generates comprehensive E2E test suites with Playwright that ensure application reliability through page objects, fixtures, and visual testing.

When to Use This Prompt

This Playwright prompt is ideal for developers working on:

  • Playwright applications requiring modern best practices and optimal performance
  • Projects that need production-ready Playwright code with proper error handling
  • Teams looking to standardize their playwright development workflow
  • Developers wanting to learn industry-standard Playwright patterns and techniques

By using this prompt, you can save hours of manual coding and ensure best practices are followed from the start. It's particularly valuable for teams looking to maintain consistency across their playwright implementations.

How to Use

  1. Copy the prompt - Click the copy button above to copy the entire prompt to your clipboard
  2. Paste into your AI assistant - Use with Claude, ChatGPT, Cursor, or any AI coding tool
  3. Customize as needed - Adjust the prompt based on your specific requirements
  4. Review the output - Always review generated code for security and correctness
💡 Pro Tip: For best results, provide context about your project structure and any specific constraints or preferences you have.

Best Practices

  • ✓ Always review generated code for security vulnerabilities before deploying
  • ✓ Test the Playwright code in a development environment first
  • ✓ Customize the prompt output to match your project's coding standards
  • ✓ Keep your AI assistant's context window in mind for complex requirements
  • ✓ Version control your prompts alongside your code for reproducibility

Frequently Asked Questions

Can I use this Playwright prompt commercially?

Yes! All prompts on Antigravity AI Directory are free to use for both personal and commercial projects. No attribution required, though it's always appreciated.

Which AI assistants work best with this prompt?

This prompt works excellently with Claude, ChatGPT, Cursor, GitHub Copilot, and other modern AI coding assistants. For best results, use models with large context windows.

How do I customize this prompt for my specific needs?

You can modify the prompt by adding specific requirements, constraints, or preferences. For Playwright projects, consider mentioning your framework version, coding style, and any specific libraries you're using.

Related Prompts

💬 Comments

Loading comments...