mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-01 08:34:07 +00:00
223 lines
8.6 KiB
TypeScript
223 lines
8.6 KiB
TypeScript
import fs from 'fs';
|
|
import path from 'path';
|
|
import { test, expect } from '../../../playwright';
|
|
import {
|
|
sendRequestAndWaitForResponse, closeAllCollections, selectEnvironment,
|
|
openCollection, openRequest, selectResponsePaneTab
|
|
} from '../../utils/page';
|
|
import { runCollection, validateRunnerResults } from '../../utils/page/runner';
|
|
|
|
// The test PEM file is gitignored (*.pem). Write it to both fixture directories
|
|
// at module load time so collectionFixturePath includes it when copying.
|
|
|
|
const { TEST_RSA_PRIVATE_KEY } = require('../../../packages/bruno-tests/src/auth/oauth1');
|
|
|
|
const fixtureBase = path.join(__dirname, 'fixtures', 'collections');
|
|
for (const subdir of ['bru', 'yml']) {
|
|
const pemPath = path.join(fixtureBase, subdir, 'test-private-key.pem');
|
|
if (!fs.existsSync(pemPath)) {
|
|
fs.writeFileSync(pemPath, TEST_RSA_PRIVATE_KEY);
|
|
}
|
|
}
|
|
|
|
const BRU_COLLECTION = 'oauth1-testbench-bru';
|
|
const YML_COLLECTION = 'oauth1-testbench-yml';
|
|
|
|
const requests = [
|
|
{ name: 'OAuth1 HMAC-SHA1 200', status: 200 },
|
|
{ name: 'OAuth1 HMAC-SHA1 401', status: 401 },
|
|
{ name: 'OAuth1 HMAC-SHA1 POST 200', status: 200 },
|
|
{ name: 'OAuth1 HMAC-SHA1 Query Params 200', status: 200 },
|
|
{ name: 'OAuth1 HMAC-SHA256 200', status: 200 },
|
|
{ name: 'OAuth1 HMAC-SHA256 401', status: 401 },
|
|
{ name: 'OAuth1 HMAC-SHA512 200', status: 200 },
|
|
{ name: 'OAuth1 HMAC-SHA512 401', status: 401 },
|
|
{ name: 'OAuth1 PLAINTEXT 200', status: 200 },
|
|
{ name: 'OAuth1 PLAINTEXT 401', status: 401 },
|
|
{ name: 'OAuth1 PLAINTEXT Query Params 200', status: 200 },
|
|
{ name: 'OAuth1 RSA-SHA1 200', status: 200 },
|
|
{ name: 'OAuth1 RSA-SHA1 Query Params 200', status: 200 },
|
|
{ name: 'OAuth1 RSA-SHA256 200', status: 200 },
|
|
{ name: 'OAuth1 RSA-SHA512 200', status: 200 },
|
|
{ name: 'OAuth1 RSA-SHA1 Variable Key 200', status: 200 },
|
|
{ name: 'OAuth1 RSA-SHA1 File Key 200', status: 200 },
|
|
{ name: 'OAuth1 HMAC-SHA1 Body 200', status: 200 },
|
|
{ name: 'OAuth1 PLAINTEXT Body 200', status: 200 },
|
|
{ name: 'OAuth1 HMAC-SHA256 Body 200', status: 200 },
|
|
{ name: 'OAuth1 RSA-SHA1 Body 200', status: 200 },
|
|
{ name: 'OAuth1 RSA-SHA1 Body formurlencoded 200', status: 200 },
|
|
{ name: 'OAuth1 HMAC-SHA1 Body JSON 200', status: 200 }
|
|
];
|
|
|
|
const sendAllRequests = async (page, collectionName: string) => {
|
|
await openCollection(page, collectionName);
|
|
await selectEnvironment(page, 'Local', 'collection');
|
|
|
|
for (const { name, status } of requests) {
|
|
await test.step(name, async () => {
|
|
await openRequest(page, collectionName, name);
|
|
await sendRequestAndWaitForResponse(page, status);
|
|
});
|
|
}
|
|
};
|
|
|
|
const runAndValidate = async (page, collectionName: string) => {
|
|
await runCollection(page, collectionName);
|
|
await validateRunnerResults(page, {
|
|
totalRequests: requests.length,
|
|
passed: requests.length,
|
|
failed: 0
|
|
});
|
|
};
|
|
|
|
/**
|
|
* After sending a request, switch to the Timeline tab, expand the latest timeline row,
|
|
* and return its locator. The expanded detail panel defaults to the Request tab,
|
|
* which shows the sent URL, headers and body (what OAuth1 placement assertions need).
|
|
*/
|
|
const openTimelineRequest = async (page) => {
|
|
await selectResponsePaneTab(page, 'Timeline');
|
|
|
|
const row = page.locator('.timeline-container .tl-row-wrap').first();
|
|
await row.locator('.tl-row').click();
|
|
|
|
return row;
|
|
};
|
|
|
|
const verifyPlacement = async (page, collectionName: string, requestName: string, placement: 'header' | 'query' | 'body') => {
|
|
await openRequest(page, collectionName, requestName);
|
|
await sendRequestAndWaitForResponse(page, 200);
|
|
|
|
const row = await openTimelineRequest(page);
|
|
const detail = row.locator('.tl-detail');
|
|
|
|
if (placement === 'header') {
|
|
const headers = detail.locator('.tl-headers-table');
|
|
await expect(headers).toContainText('Authorization');
|
|
await expect(headers).toContainText('OAuth');
|
|
} else if (placement === 'query') {
|
|
await expect(detail.locator('.tl-header-url-text')).toContainText('oauth_consumer_key');
|
|
} else {
|
|
// Body: oauth params should be in the request body, not in URL or Authorization header
|
|
await expect(detail.locator('.tl-header-url-text')).not.toContainText('oauth_consumer_key');
|
|
const body = detail.locator('.tl-block').filter({
|
|
has: page.locator('.tl-block-h', { hasText: 'Body' })
|
|
});
|
|
await expect(body).toContainText('oauth_consumer_key');
|
|
}
|
|
};
|
|
|
|
test.describe('OAuth 1.0 Runner', () => {
|
|
test.afterAll(async ({ pageWithUserData: page }) => {
|
|
await closeAllCollections(page);
|
|
});
|
|
|
|
test.describe('[bru]', () => {
|
|
test('Send individual requests', async ({ pageWithUserData: page }) => {
|
|
test.setTimeout(3 * 60 * 1000);
|
|
await sendAllRequests(page, BRU_COLLECTION);
|
|
});
|
|
|
|
test('Run collection and verify all assertions pass', async ({ pageWithUserData: page }) => {
|
|
test.setTimeout(3 * 60 * 1000);
|
|
await runAndValidate(page, BRU_COLLECTION);
|
|
});
|
|
|
|
test('Verify Add Params To placement via timeline', async ({ pageWithUserData: page }) => {
|
|
test.setTimeout(3 * 60 * 1000);
|
|
await openCollection(page, BRU_COLLECTION);
|
|
await selectEnvironment(page, 'Local', 'collection');
|
|
|
|
await test.step('Header: HMAC-SHA1', async () => {
|
|
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 HMAC-SHA1 200', 'header');
|
|
});
|
|
|
|
await test.step('Query Params: HMAC-SHA1', async () => {
|
|
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 HMAC-SHA1 Query Params 200', 'query');
|
|
});
|
|
|
|
await test.step('Query Params: PLAINTEXT', async () => {
|
|
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 PLAINTEXT Query Params 200', 'query');
|
|
});
|
|
|
|
await test.step('Query Params: RSA-SHA1', async () => {
|
|
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 RSA-SHA1 Query Params 200', 'query');
|
|
});
|
|
|
|
await test.step('Body: HMAC-SHA1', async () => {
|
|
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 HMAC-SHA1 Body 200', 'body');
|
|
});
|
|
|
|
await test.step('Body: PLAINTEXT', async () => {
|
|
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 PLAINTEXT Body 200', 'body');
|
|
});
|
|
|
|
await test.step('Body: HMAC-SHA256', async () => {
|
|
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 HMAC-SHA256 Body 200', 'body');
|
|
});
|
|
|
|
await test.step('Body: RSA-SHA1', async () => {
|
|
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 RSA-SHA1 Body 200', 'body');
|
|
});
|
|
|
|
await test.step('Body: HMAC-SHA1 JSON (non-form body)', async () => {
|
|
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 HMAC-SHA1 Body JSON 200', 'body');
|
|
});
|
|
});
|
|
});
|
|
|
|
test.describe('[yml]', () => {
|
|
test('Send individual requests', async ({ pageWithUserData: page }) => {
|
|
test.setTimeout(3 * 60 * 1000);
|
|
await sendAllRequests(page, YML_COLLECTION);
|
|
});
|
|
|
|
test('Run collection and verify all assertions pass', async ({ pageWithUserData: page }) => {
|
|
test.setTimeout(3 * 60 * 1000);
|
|
await runAndValidate(page, YML_COLLECTION);
|
|
});
|
|
|
|
test('Verify Add Params To placement via timeline', async ({ pageWithUserData: page }) => {
|
|
test.setTimeout(3 * 60 * 1000);
|
|
await openCollection(page, YML_COLLECTION);
|
|
await selectEnvironment(page, 'Local', 'collection');
|
|
|
|
await test.step('Header: HMAC-SHA1', async () => {
|
|
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 HMAC-SHA1 200', 'header');
|
|
});
|
|
|
|
await test.step('Query Params: HMAC-SHA1', async () => {
|
|
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 HMAC-SHA1 Query Params 200', 'query');
|
|
});
|
|
|
|
await test.step('Query Params: PLAINTEXT', async () => {
|
|
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 PLAINTEXT Query Params 200', 'query');
|
|
});
|
|
|
|
await test.step('Query Params: RSA-SHA1', async () => {
|
|
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 RSA-SHA1 Query Params 200', 'query');
|
|
});
|
|
|
|
await test.step('Body: HMAC-SHA1', async () => {
|
|
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 HMAC-SHA1 Body 200', 'body');
|
|
});
|
|
|
|
await test.step('Body: PLAINTEXT', async () => {
|
|
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 PLAINTEXT Body 200', 'body');
|
|
});
|
|
|
|
await test.step('Body: HMAC-SHA256', async () => {
|
|
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 HMAC-SHA256 Body 200', 'body');
|
|
});
|
|
|
|
await test.step('Body: RSA-SHA1', async () => {
|
|
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 RSA-SHA1 Body 200', 'body');
|
|
});
|
|
|
|
await test.step('Body: HMAC-SHA1 JSON (non-form body)', async () => {
|
|
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 HMAC-SHA1 Body JSON 200', 'body');
|
|
});
|
|
});
|
|
});
|
|
});
|