Initial commit: Full Crawl API implementation
This commit is contained in:
105
e2e/api.spec.ts
Normal file
105
e2e/api.spec.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
const API_URL = process.env.API_URL || 'http://localhost:3000';
|
||||
|
||||
test.describe('Crawl API E2E', () => {
|
||||
let apiKey: string;
|
||||
let token: string;
|
||||
|
||||
test.beforeAll(async ({ request }) => {
|
||||
// Register test user
|
||||
const register = await request.post(`${API_URL}/api/auth/register`, {
|
||||
data: {
|
||||
email: `e2e_${Date.now()}@test.com`,
|
||||
password: 'testpassword123'
|
||||
}
|
||||
});
|
||||
const registerData = await register.json();
|
||||
token = registerData.token;
|
||||
|
||||
// Create API key
|
||||
const key = await request.post(`${API_URL}/api/auth/api-keys`, {
|
||||
headers: { 'x-auth-token': token },
|
||||
data: { name: 'E2E Key' }
|
||||
});
|
||||
const keyData = await key.json();
|
||||
apiKey = keyData.key;
|
||||
});
|
||||
|
||||
test('POST /api/screenshot returns success', async ({ request }) => {
|
||||
const res = await request.post(`${API_URL}/api/screenshot`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-api-key': apiKey,
|
||||
},
|
||||
data: {
|
||||
url: 'https://example.com',
|
||||
options: { fullPage: true }
|
||||
}
|
||||
});
|
||||
|
||||
expect(res.status()).toBe(200);
|
||||
const data = await res.json();
|
||||
expect(data.success).toBe(true);
|
||||
expect(data.data).toBeDefined();
|
||||
expect(data.calls_remaining).toBeDefined();
|
||||
});
|
||||
|
||||
test('POST /api/content returns HTML', async ({ request }) => {
|
||||
const res = await request.post(`${API_URL}/api/content`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-api-key': apiKey,
|
||||
},
|
||||
data: { url: 'https://example.com' }
|
||||
});
|
||||
|
||||
expect(res.status()).toBe(200);
|
||||
const data = await res.json();
|
||||
expect(data.success).toBe(true);
|
||||
expect(data.data.html).toContain('<html');
|
||||
});
|
||||
|
||||
test('POST /api/json returns structured data', async ({ request }) => {
|
||||
const res = await request.post(`${API_URL}/api/json`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-api-key': apiKey,
|
||||
},
|
||||
data: { url: 'https://example.com' }
|
||||
});
|
||||
|
||||
expect(res.status()).toBe(200);
|
||||
const data = await res.json();
|
||||
expect(data.success).toBe(true);
|
||||
expect(data.data.title).toBeDefined();
|
||||
});
|
||||
|
||||
test('GET /metrics returns Prometheus format', async ({ request }) => {
|
||||
const res = await request.get(`${API_URL}/metrics`);
|
||||
expect(res.status()).toBe(200);
|
||||
const text = await res.text();
|
||||
expect(text).toContain('api_requests_total');
|
||||
});
|
||||
|
||||
test('POST /api/screenshot without API key returns 401', async ({ request }) => {
|
||||
const res = await request.post(`${API_URL}/api/screenshot`, {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: { url: 'https://example.com' }
|
||||
});
|
||||
expect(res.status()).toBe(401);
|
||||
});
|
||||
|
||||
test('POST /api/screenshot with invalid URL returns 400', async ({ request }) => {
|
||||
const res = await request.post(`${API_URL}/api/screenshot`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-api-key': apiKey,
|
||||
},
|
||||
data: { url: 'not-a-valid-url' }
|
||||
});
|
||||
expect(res.status()).toBe(200);
|
||||
const data = await res.json();
|
||||
expect(data.success).toBe(false);
|
||||
});
|
||||
});
|
||||
11
e2e/package.json
Normal file
11
e2e/package.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "crawlapi-e2e",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"test": "playwright test",
|
||||
"test:ui": "playwright test --ui"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.49.0"
|
||||
}
|
||||
}
|
||||
20
e2e/playwright.config.ts
Normal file
20
e2e/playwright.config.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
export default defineConfig({
|
||||
testDir: '.',
|
||||
fullyParallel: true,
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
reporter: 'html',
|
||||
use: {
|
||||
baseURL: process.env.API_URL || 'http://localhost:3000',
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: 'api',
|
||||
testMatch: /.*\.spec\.ts/,
|
||||
},
|
||||
],
|
||||
});
|
||||
Reference in New Issue
Block a user