Playwright - Modern End-to-End Testing Framework

Analysis of Playwright and its role in testing security controls in Cursor environments.

Table of contents

  1. Overview
    1. Framework Information
  2. Core Capabilities
    1. 1. Cross-Browser Testing
    2. 2. Auto-Wait
    3. 3. Security Testing Use Cases
  3. Integration with CI/CD
  4. Resources

Overview

Playwright is a modern, open-source testing framework from Microsoft that enables reliable end-to-end testing for web applications. It supports multiple browsers and provides powerful automation capabilities.

Framework Information

   
Framework Playwright
Developer Microsoft
Launched 2020
Language Support TypeScript, JavaScript, Python, .NET, Java
Website https://playwright.dev
License Apache 2.0 (Open Source)
Notable Built by creators of Puppeteer (Google Chrome team)

Core Capabilities

1. Cross-Browser Testing

Browser Support:

  • Chromium (Chrome, Edge)
  • Firefox
  • WebKit (Safari)
  • Mobile emulation

2. Auto-Wait

Reliability Feature:

1
2
3
4
5
// Playwright automatically waits for elements
await page.click('button#login');  // Waits for button to be clickable
await page.fill('#api-key', apiKey);  // Waits for input to be enabled

// No manual waits needed (vs Selenium)

3. Security Testing Use Cases

Test Okta SSO Flow:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// Test authentication for Cursor web portal
import { test, expect } from '@playwright/test';

test('Okta SSO login enforces MFA', async ({ page }) => {
  // 1. Navigate to Cursor portal
  await page.goto('https://cursor.company.com');
  
  // 2. Click SSO login
  await page.click('button:has-text("Sign in with SSO")');
  
  // 3. Enter company domain
  await page.fill('#domain', 'company.com');
  await page.click('#next');
  
  // 4. Redirected to Okta
  await expect(page).toHaveURL(/.*okta\.com.*/);
  
  // 5. Enter credentials
  await page.fill('#username', process.env.TEST_USER);
  await page.fill('#password', process.env.TEST_PASSWORD);
  await page.click('#submit');
  
  // 6. MFA challenge should appear
  await expect(page.locator('text=Verify with Okta')).toBeVisible();
  
  // 7. Complete MFA (using test account)
  await page.click('#push-notification');
  
  // Wait for approval (in test, auto-approve)
  await page.waitForURL('https://cursor.company.com/dashboard');
  
  // 8. Verify logged in
  await expect(page.locator('text=Welcome')).toBeVisible();
});

test('Cannot bypass Okta MFA', async ({ page }) => {
  // Attempt to access dashboard directly
  await page.goto('https://cursor.company.com/dashboard');
  
  // Should redirect to login
  await expect(page).toHaveURL(/.*okta\.com.*/);
  
  // Even with valid session cookie manipulation
  await page.context().addCookies([{
    name: 'session',
    value: 'fake-session-token',
    domain: 'cursor.company.com',
    path: '/'
  }]);
  
  await page.goto('https://cursor.company.com/dashboard');
  
  // Should still redirect (MFA required)
  await expect(page).toHaveURL(/.*okta\.com.*/);
});

Test DLP Blocking:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
test('Purview DLP blocks API key in Teams', async ({ page }) => {
  await page.goto('https://teams.microsoft.com');
  
  // Login...
  
  // Try to send Azure OpenAI key in chat
  const fakeApiKey = 'sk-proj-test1234567890abcdef';
  await page.fill('#message-input', `Here's the API key: ${fakeApiKey}`);
  await page.click('#send-button');
  
  // Should see DLP block message
  await expect(page.locator('text=blocked by policy')).toBeVisible({ timeout: 5000 });
  
  // Message should not be sent
  const messages = await page.locator('.message-content').allTextContents();
  expect(messages).not.toContain(fakeApiKey);
});

Integration with CI/CD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Azure DevOps pipeline
- task: PowerShell@2
  displayName: 'Run Playwright Security Tests'
  inputs:
    targetType: 'inline'
    script: |
      npm install
      npx playwright install
      npx playwright test --grep @security
      
- task: PublishTestResults@2
  condition: always()
  inputs:
    testResultsFormat: 'JUnit'
    testResultsFiles: '**/test-results.xml'
    failTaskOnFailedTests: true

Resources


Last Updated: October 10, 2025