@nestjsvn/swagger-sse
Version:
OpenAPI documentation and interactive Swagger UI for NestJS Server-Sent Events endpoints
210 lines (209 loc) • 11 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const setup_1 = require("./setup");
const test_controllers_1 = require("./test-controllers");
describe('Cross-Browser Compatibility E2E Tests', () => {
const browsers = ['chromium', 'firefox', 'webkit'];
describe.each(browsers)('Browser: %s', browserType => {
let context;
beforeAll(async () => {
context = await setup_1.E2ETestSetup.createContext(`cross-browser-${browserType}`, {
controllers: [test_controllers_1.TestEventsController],
}, browserType);
});
afterAll(async () => {
await setup_1.E2ETestSetup.cleanup(`cross-browser-${browserType}`);
});
it('should load Swagger UI correctly', async () => {
await context.page.goto(`${context.baseUrl}/api-docs`);
// Wait for Swagger UI to load
await context.page.waitForSelector('.swagger-ui', { timeout: 10000 });
// Verify basic UI elements are present
const title = await context.page.textContent('h2.title');
expect(title).toContain('Test API');
// Check for SSE endpoints
const endpoints = await context.page.$$('[data-path*="/test-events"]');
expect(endpoints.length).toBeGreaterThan(0);
});
it('should establish SSE connections', async () => {
await context.page.goto(`${context.baseUrl}/api-docs`);
await context.page.waitForSelector('.swagger-ui');
await context.page.click('[data-path="/test-events/basic"] .opblock-summary');
// Test SSE connection
await setup_1.SSETestHelpers.connectToSSE(context.page);
const status = await context.page.getAttribute('[data-testid="sse-status"]', 'data-status');
expect(status).toBe('connected');
});
it('should receive and display events', async () => {
await context.page.goto(`${context.baseUrl}/api-docs`);
await context.page.waitForSelector('.swagger-ui');
await context.page.click('[data-path="/test-events/basic"] .opblock-summary');
await setup_1.SSETestHelpers.connectToSSE(context.page);
await setup_1.SSETestHelpers.waitForSSEEvents(context.page, 1, 10000);
const events = await setup_1.SSETestHelpers.getSSEEvents(context.page);
expect(events.length).toBeGreaterThan(0);
});
it('should handle EventSource API correctly', async () => {
await context.page.goto(`${context.baseUrl}/api-docs`);
// Check if EventSource is available
const hasEventSource = await context.page.evaluate(() => {
return typeof EventSource !== 'undefined';
});
expect(hasEventSource).toBe(true);
// Test EventSource functionality
const eventSourceWorks = await context.page.evaluate(() => {
try {
const es = new EventSource('data:text/plain,');
es.close();
return true;
}
catch (error) {
return false;
}
});
expect(eventSourceWorks).toBe(true);
});
it('should handle CSS and styling correctly', async () => {
await context.page.goto(`${context.baseUrl}/api-docs`);
await context.page.waitForSelector('.swagger-ui');
// Check if SSE plugin CSS is loaded
const _hasSSEStyles = await context.page.evaluate(() => {
const stylesheets = Array.from(document.styleSheets);
return stylesheets.some(sheet => {
try {
const rules = Array.from(sheet.cssRules || []);
return rules.some(rule => rule.cssText && rule.cssText.includes('sse-'));
}
catch {
return false;
}
});
});
// Note: This might be false if CSS is inlined, which is acceptable
// The important thing is that the UI renders correctly
const uiRendered = (await context.page.$('.swagger-ui')) !== null;
expect(uiRendered).toBe(true);
});
});
describe('Browser-Specific Features', () => {
it('should work with Chrome DevTools Protocol', async () => {
const context = await setup_1.E2ETestSetup.createContext('chrome-devtools', { controllers: [test_controllers_1.TestEventsController] }, 'chromium');
try {
// Enable network domain for monitoring
const client = await context.page.context().newCDPSession(context.page);
await client.send('Network.enable');
await context.page.goto(`${context.baseUrl}/api-docs`);
await context.page.waitForSelector('.swagger-ui');
await context.page.click('[data-path="/test-events/basic"] .opblock-summary');
// Monitor network requests
const networkRequests = [];
client.on('Network.requestWillBeSent', (params) => {
networkRequests.push(params);
});
await setup_1.SSETestHelpers.connectToSSE(context.page);
// Wait a bit for network activity
await context.page.waitForTimeout(2000);
// Should have SSE connection request
const sseRequest = networkRequests.find(req => req.request.url.includes('/test-events/basic'));
expect(sseRequest).toBeDefined();
}
finally {
await setup_1.E2ETestSetup.cleanup('chrome-devtools');
}
});
it('should handle Firefox-specific EventSource behavior', async () => {
const context = await setup_1.E2ETestSetup.createContext('firefox-specific', { controllers: [test_controllers_1.TestEventsController] }, 'firefox');
try {
await context.page.goto(`${context.baseUrl}/api-docs`);
await context.page.waitForSelector('.swagger-ui');
await context.page.click('[data-path="/test-events/basic"] .opblock-summary');
// Firefox has specific EventSource implementation details
const firefoxEventSourceFeatures = await context.page.evaluate(() => {
const es = new EventSource('data:text/plain,');
const features = {
hasReadyState: 'readyState' in es,
hasUrl: 'url' in es,
hasWithCredentials: 'withCredentials' in es,
};
es.close();
return features;
});
expect(firefoxEventSourceFeatures.hasReadyState).toBe(true);
expect(firefoxEventSourceFeatures.hasUrl).toBe(true);
}
finally {
await setup_1.E2ETestSetup.cleanup('firefox-specific');
}
});
it('should handle Safari/WebKit-specific behavior', async () => {
const context = await setup_1.E2ETestSetup.createContext('webkit-specific', { controllers: [test_controllers_1.TestEventsController] }, 'webkit');
try {
await context.page.goto(`${context.baseUrl}/api-docs`);
await context.page.waitForSelector('.swagger-ui');
// WebKit has specific handling for CORS and EventSource
const webkitFeatures = await context.page.evaluate(() => {
return {
userAgent: navigator.userAgent,
hasEventSource: typeof EventSource !== 'undefined',
supportsCORS: 'withCredentials' in new XMLHttpRequest(),
};
});
expect(webkitFeatures.hasEventSource).toBe(true);
expect(webkitFeatures.supportsCORS).toBe(true);
}
finally {
await setup_1.E2ETestSetup.cleanup('webkit-specific');
}
});
});
describe('Responsive Design and Mobile', () => {
it('should work on mobile viewport sizes', async () => {
const context = await setup_1.E2ETestSetup.createContext('mobile-responsive', {
controllers: [test_controllers_1.TestEventsController],
});
try {
// Set mobile viewport
await context.page.setViewportSize({ width: 375, height: 667 });
await context.page.goto(`${context.baseUrl}/api-docs`);
await context.page.waitForSelector('.swagger-ui');
// Check if UI is responsive
const isResponsive = await context.page.evaluate(() => {
const swaggerUI = document.querySelector('.swagger-ui');
if (!swaggerUI)
return false;
const rect = swaggerUI.getBoundingClientRect();
return rect.width <= window.innerWidth;
});
expect(isResponsive).toBe(true);
// Test SSE functionality on mobile
await context.page.click('[data-path="/test-events/basic"] .opblock-summary');
await setup_1.SSETestHelpers.connectToSSE(context.page);
const status = await context.page.getAttribute('[data-testid="sse-status"]', 'data-status');
expect(status).toBe('connected');
}
finally {
await setup_1.E2ETestSetup.cleanup('mobile-responsive');
}
});
it('should handle touch interactions', async () => {
const context = await setup_1.E2ETestSetup.createContext('touch-interactions', {
controllers: [test_controllers_1.TestEventsController],
});
try {
// Enable touch events
await context.page.setViewportSize({ width: 375, height: 667 });
await context.page.goto(`${context.baseUrl}/api-docs`);
await context.page.waitForSelector('.swagger-ui');
// Use tap instead of click for mobile
await context.page.tap('[data-path="/test-events/basic"] .opblock-summary');
await context.page.tap('[data-testid="sse-connect-btn"]');
await context.page.waitForSelector('[data-testid="sse-status"][data-status="connected"]');
const status = await context.page.getAttribute('[data-testid="sse-status"]', 'data-status');
expect(status).toBe('connected');
}
finally {
await setup_1.E2ETestSetup.cleanup('touch-interactions');
}
});
});
});