Skip to content

Commit 3e3c6e8

Browse files
committed
feat: add comprehensive functional tests for deals page
1 parent f49e295 commit 3e3c6e8

File tree

7 files changed

+387
-0
lines changed

7 files changed

+387
-0
lines changed

tests/deals/deal-details.spec.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test.describe('Deal Details Page Functionality', () => {
4+
test('Explore deal details tabs and information', async ({ page }) => {
5+
// Navigate to a deal detail page
6+
await page.goto('https://explorer.iex.ec');
7+
await page.getByRole('link', { name: 'View all deals' }).click();
8+
await page.waitForSelector('table');
9+
10+
// Click on first deal row to navigate to details
11+
const firstRow = page.getByRole('row').filter({ hasNot: page.getByRole('columnheader') }).first();
12+
const dealIdCell = firstRow.getByRole('cell').first();
13+
// Click on the text content of the deal ID, not the copy button
14+
const dealIdText = dealIdCell.getByText(/0x[a-fA-F0-9]+/);
15+
await dealIdText.click();
16+
17+
// Wait for deal details page to load
18+
await page.waitForSelector('table');
19+
20+
// Verify DETAILS tab is active by default
21+
const detailsTab = page.getByRole('button', { name: 'DETAILS' });
22+
await expect(detailsTab).toBeVisible();
23+
24+
// Verify comprehensive deal information is displayed
25+
const dealInfoItems = [
26+
'Dealid',
27+
'Category',
28+
'Dataset',
29+
'Workerpool',
30+
'Status'
31+
];
32+
33+
for (const item of dealInfoItems) {
34+
await expect(page.getByText(item).first()).toBeVisible();
35+
}
36+
37+
// Check for App specifically in the table rows
38+
await expect(page.getByRole('cell', { name: 'App', exact: true })).toBeVisible();
39+
40+
// Click on TASKS tab
41+
const tasksTab = page.getByRole('button', { name: 'TASKS' });
42+
await tasksTab.click();
43+
44+
// Verify tasks table displays with expected columns
45+
const taskHeaders = ['Index', 'Task', 'Status', 'Deadline'];
46+
47+
for (const header of taskHeaders) {
48+
await expect(page.getByRole('columnheader', { name: header })).toBeVisible();
49+
}
50+
51+
// Verify task rows show task IDs with copy buttons
52+
const taskRows = page.getByRole('row').filter({ hasNot: page.getByRole('columnheader') });
53+
const firstTaskRow = taskRows.first();
54+
55+
if (await firstTaskRow.isVisible()) {
56+
await expect(firstTaskRow.getByRole('button')).toBeVisible(); // Copy button for task ID
57+
}
58+
59+
// Click on ASSOCIATED DEALS tab if available
60+
const associatedDealsTab = page.getByRole('button', { name: 'ASSOCIATED DEALS' });
61+
62+
if (await associatedDealsTab.isVisible()) {
63+
await associatedDealsTab.click();
64+
// Verify content is displayed (more specific selector)
65+
await expect(page.locator('main table')).toBeVisible();
66+
}
67+
});
68+
});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test.describe('Deals Table Navigation and Display', () => {
4+
test('Navigate to deals page from homepage', async ({ page }) => {
5+
// Navigate to the iExec explorer homepage
6+
await page.goto('https://explorer.iex.ec');
7+
8+
// Verify the 'Latest deals' section is visible
9+
await expect(page.getByRole('heading', { name: 'Latest deals' })).toBeVisible();
10+
11+
// Click on 'View all deals' link
12+
await page.getByRole('link', { name: 'View all deals' }).click();
13+
14+
// Verify navigation to deals page with correct URL
15+
await expect(page).toHaveURL(/.*\/deals$/);
16+
17+
// Verify deals page header displays 'Deals' with deal icon
18+
await expect(page.getByRole('heading', { name: /Deals/ })).toBeVisible();
19+
20+
// Verify breadcrumb navigation shows: Homepage > All deals
21+
const breadcrumb = page.locator('[role="navigation"][aria-label="breadcrumb"], nav')
22+
.filter({ has: page.locator('text=Homepage') });
23+
await expect(breadcrumb).toBeVisible();
24+
await expect(breadcrumb.getByText('All deals')).toBeVisible();
25+
});
26+
});
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test.describe('Deals Table Structure and Data Display', () => {
4+
test('Verify deals table structure and data display', async ({ page }) => {
5+
// Navigate to deals page
6+
await page.goto('https://explorer.iex.ec');
7+
await page.getByRole('link', { name: 'View all deals' }).click();
8+
9+
// Wait for table to load with data
10+
await page.waitForSelector('table');
11+
12+
// Verify table headers are present
13+
const expectedHeaders = ['Deal', 'App', 'Workerpool', 'Dataset', 'Time', 'Success', 'Price'];
14+
15+
for (const header of expectedHeaders) {
16+
await expect(page.getByRole('columnheader', { name: header }).first()).toBeVisible();
17+
}
18+
19+
// Verify table contains multiple deal rows with data
20+
const tableRows = page.getByRole('row').filter({ hasNot: page.getByRole('columnheader') });
21+
// Wait for at least one row to have content
22+
await expect(tableRows.first().getByText(/0x[a-fA-F0-9]+/).first()).toBeVisible();
23+
24+
// Verify we have at least one row
25+
const rowCount = await tableRows.count();
26+
expect(rowCount).toBeGreaterThan(0);
27+
28+
// Verify each row displays truncated addresses with copy buttons
29+
const firstRow = tableRows.first();
30+
const buttonCount = await firstRow.getByRole('button').count();
31+
expect(buttonCount).toBeGreaterThanOrEqual(3); // At least 3 copy buttons per row
32+
33+
// Verify time column shows relative time (e.g., '14h ago')
34+
await expect(firstRow.getByText(/\d+[hdm]\s+ago|\d+d\s+ago/)).toBeVisible();
35+
36+
// Verify success column shows percentage (e.g., '100%')
37+
await expect(firstRow.getByText(/\d+%/)).toBeVisible();
38+
39+
// Verify price column shows amount with RLC token symbol
40+
await expect(firstRow.getByText(/\d+(\.\d+)?\s+RLC/)).toBeVisible();
41+
42+
// Verify dataset column can show 'Datasets bulk' or specific addresses
43+
const datasetCells = page.getByRole('cell').filter({ hasText: /Datasets bulk|0x[a-fA-F0-9]+/ });
44+
const datasetCellCount = await datasetCells.count();
45+
expect(datasetCellCount).toBeGreaterThanOrEqual(1);
46+
});
47+
});

tests/deals/pagination.spec.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test.describe('Pagination Testing', () => {
4+
test('Test pagination controls and navigation', async ({ page }) => {
5+
// Navigate to deals page
6+
await page.goto('https://explorer.iex.ec');
7+
await page.getByRole('link', { name: 'View all deals' }).click();
8+
9+
// Wait for table and pagination to load
10+
await page.waitForSelector('table');
11+
await page.waitForSelector('nav[role="navigation"], [role="navigation"]');
12+
13+
// Verify pagination controls are present at bottom
14+
const pagination = page.locator('nav').filter({ has: page.getByText(/\d+/) });
15+
await expect(pagination).toBeVisible();
16+
17+
// Note the current page (should be page 1)
18+
await expect(page).toHaveURL(/^(?!.*dealsPage).*$/); // No page parameter means page 1
19+
20+
// Click on page 2
21+
const page2Button = pagination.getByText('2').first();
22+
if (await page2Button.isVisible()) {
23+
await page2Button.click();
24+
25+
// Verify URL updates with ?dealsPage=2 parameter
26+
await expect(page).toHaveURL(/.*dealsPage=2.*/);
27+
28+
// Verify different deal data loads on page 2
29+
await page.waitForSelector('table');
30+
await expect(page.getByRole('row').filter({ hasNot: page.getByRole('columnheader') })).toHaveCount({ min: 1 });
31+
32+
// Click on page 3 if available
33+
const page3Button = pagination.getByText('3').first();
34+
if (await page3Button.isVisible()) {
35+
await page3Button.click();
36+
37+
// Verify URL updates and new data loads
38+
await expect(page).toHaveURL(/.*dealsPage=3.*/);
39+
await page.waitForSelector('table');
40+
}
41+
42+
// Test Previous button
43+
const previousButton = pagination.getByText('Previous');
44+
if (await previousButton.isVisible()) {
45+
await previousButton.click();
46+
// Should go back one page
47+
await expect(page).toHaveURL(/.*dealsPage=2.*/);
48+
}
49+
50+
// Test Next button
51+
const nextButton = pagination.getByText('Next');
52+
if (await nextButton.isVisible()) {
53+
await nextButton.click();
54+
// Should advance one page
55+
await expect(page).toHaveURL(/.*dealsPage=3.*/);
56+
}
57+
}
58+
});
59+
});
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test.describe('Responsive Design and Accessibility', () => {
4+
test('Test responsive behavior and accessibility', async ({ page }) => {
5+
// Navigate to deals page on desktop viewport
6+
await page.setViewportSize({ width: 1280, height: 720 });
7+
await page.goto('https://explorer.iex.ec/arbitrum-mainnet/deals');
8+
9+
// Wait for table to load
10+
await page.waitForSelector('table');
11+
12+
// Verify table displays properly on desktop (be specific about the deals table)
13+
const table = page.locator('table').first();
14+
await expect(table).toBeVisible();
15+
16+
// Verify all columns are visible on desktop
17+
const columnHeaders = ['Deal', 'App', 'Workerpool', 'Dataset', 'Time', 'Success', 'Price'];
18+
for (const header of columnHeaders) {
19+
await expect(page.getByRole('columnheader', { name: header }).first()).toBeVisible();
20+
}
21+
22+
// Resize to tablet viewport
23+
await page.setViewportSize({ width: 768, height: 1024 });
24+
await page.waitForTimeout(1000);
25+
26+
// Verify table remains functional
27+
await expect(table).toBeVisible();
28+
29+
// Resize to mobile viewport
30+
await page.setViewportSize({ width: 375, height: 667 });
31+
await page.waitForTimeout(1000);
32+
33+
// Verify table remains functional and readable on mobile
34+
await expect(table).toBeVisible();
35+
36+
// Test that at least some content is still visible
37+
const tableRows = page.getByRole('row').filter({ hasNot: page.getByRole('columnheader') });
38+
await expect(tableRows.first()).toBeVisible();
39+
40+
// Reset to desktop for keyboard navigation testing
41+
await page.setViewportSize({ width: 1280, height: 720 });
42+
await page.waitForTimeout(1000);
43+
44+
// Test keyboard navigation through table rows
45+
// Focus on the first data row
46+
const firstRow = page.getByRole('row').filter({ hasNot: page.getByRole('columnheader') }).first();
47+
await firstRow.focus();
48+
49+
// Test tab navigation through interactive elements
50+
const copyButtons = page.getByRole('button').filter({ hasText: '' }); // Copy buttons typically have no text
51+
const buttonCount = await copyButtons.count();
52+
53+
if (buttonCount > 0) {
54+
// Focus on first copy button
55+
await copyButtons.first().focus();
56+
57+
// Test that focus is visible (button should be focused)
58+
await expect(copyButtons.first()).toBeFocused();
59+
60+
// Test tab navigation to next button
61+
await page.keyboard.press('Tab');
62+
63+
// Verify tab order works
64+
const focusedElement = page.locator(':focus');
65+
await expect(focusedElement).toBeVisible();
66+
}
67+
68+
// Test Enter key navigation on table row
69+
await firstRow.focus();
70+
await page.keyboard.press('Enter');
71+
72+
// Should navigate to deal details
73+
await expect(page).toHaveURL(/.*\/deal\/0x[a-fA-F0-9]+/);
74+
75+
// Test accessibility - check for proper ARIA labels and roles
76+
await page.goBack();
77+
await page.waitForSelector('table');
78+
79+
// Verify table has proper accessibility structure
80+
const dealsTable = page.locator('table').first();
81+
await expect(dealsTable).toBeVisible();
82+
83+
// Check that we have column headers
84+
const headerCount = await page.getByRole('columnheader').count();
85+
expect(headerCount).toBeGreaterThanOrEqual(5);
86+
87+
// Check for navigation landmarks
88+
const navigation = page.locator('nav, [role="navigation"]');
89+
const navCount = await navigation.count();
90+
expect(navCount).toBeGreaterThanOrEqual(1);
91+
});
92+
});

tests/deals/row-navigation.spec.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test.describe('Table Row Click Navigation', () => {
4+
test('Navigate to deal details via row click', async ({ page }) => {
5+
// Navigate to deals page
6+
await page.goto('https://explorer.iex.ec');
7+
await page.getByRole('link', { name: 'View all deals' }).click();
8+
9+
// Wait for table to load
10+
await page.waitForSelector('table');
11+
12+
// Click on the deal ID text to navigate to deal details
13+
const dealIdText = page.getByText(/0x[a-fA-F0-9]{6}\.\.\.[a-fA-F0-9]{5}/).first();
14+
15+
await dealIdText.click();
16+
17+
// Verify navigation to deal detail page
18+
await expect(page).toHaveURL(/.*\/deal\/0x[a-fA-F0-9]+/);
19+
20+
// Verify deal details page loads with comprehensive information
21+
await expect(page.getByRole('heading', { name: 'Deal details' })).toBeVisible();
22+
23+
// Verify breadcrumb shows: Homepage > All deals > Deal {truncated-id}
24+
const breadcrumb = page.locator('[role="navigation"][aria-label="breadcrumb"], nav')
25+
.filter({ has: page.locator('text=Homepage') });
26+
await expect(breadcrumb.getByText('All deals')).toBeVisible();
27+
await expect(breadcrumb.getByText(/Deal 0x[a-fA-F0-9]{3}\.\.\.[a-fA-F0-9]{5}/)).toBeVisible();
28+
29+
// Verify back button is present and functional
30+
const backButton = page.getByRole('button', { name: 'Back' });
31+
await expect(backButton).toBeVisible();
32+
33+
// Test back button functionality
34+
await backButton.click();
35+
await expect(page).toHaveURL(/.*\/deals$/);
36+
});
37+
});

0 commit comments

Comments
 (0)