Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
51c6bb8
test: migrate support case tests from IQE
catastrophe-brandon Apr 30, 2026
582df1f
fix: use symbolic timeout constants and improve async waiting
catastrophe-brandon Apr 30, 2026
7649fa4
refactor: simplify support case tests to follow clear user flow
catastrophe-brandon Apr 30, 2026
d7eebf8
fix: handle both button and link for 'Open a support case'
catastrophe-brandon Apr 30, 2026
57ff943
fix: wait for loading skeleton to complete before checking for button…
catastrophe-brandon Apr 30, 2026
f77fb27
refactor(tests): simplify support case link locator
catastrophe-brandon Apr 30, 2026
1f9548d
fix(tests): validate hostname only for external Customer Portal link
catastrophe-brandon Apr 30, 2026
9a7fbbc
docs: add detailed TODO note for unmigrated test #3
catastrophe-brandon Apr 30, 2026
3bf3a2a
fix(tests): wait for URL navigation and improve skip logic
catastrophe-brandon Apr 30, 2026
9f3aef3
fix(tests): use specific URL pattern for Customer Portal navigation
catastrophe-brandon May 1, 2026
cf7a57b
test: migrate feedback tests from IQE
catastrophe-brandon May 1, 2026
c262541
refactor: verify feedback submission success without JIRA integration
catastrophe-brandon May 1, 2026
e48e124
fix: use OUIA ID for feedback home title locator
catastrophe-brandon May 1, 2026
f4d939b
fix: use correct aria-label for feedback textarea
catastrophe-brandon May 1, 2026
eb5c1b4
fix: use textarea ID selector and wait for visibility
catastrophe-brandon May 1, 2026
e9e5e4c
fix: wait for feedback subtab visibility before clicking
catastrophe-brandon May 1, 2026
c6cd63f
refactor: combine feedback tests into comprehensive single test
catastrophe-brandon May 1, 2026
1db6019
docs: clarify test runs locally via stage hostname
catastrophe-brandon May 1, 2026
8f58a26
refactor: remove conditional skip from feedback test
catastrophe-brandon May 1, 2026
0276778
fix: use correct card text 'Share general feedback'
catastrophe-brandon May 1, 2026
3c7b70f
fix: use exact match for Back button and correct success message
catastrophe-brandon May 1, 2026
b9399eb
refactor: replace hard-coded timeouts with symbolic constants
catastrophe-brandon May 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions playwright/feedback.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { test, expect } from '@playwright/test';
import { disableCookiePrompt } from './test-utils';

/**
* Feedback Tests
*
* Migrated from IQE: iqe_platform_ui/tests/test_feedback.py
*
* These tests verify that the feedback functionality works correctly in the help panel:
* - Opening and closing feedback forms
* - Submitting feedback and creating JIRA tickets in CRCFEEDBK project
*
* Requirements:
* - PLATFORM_UI-FEEDBACK
* - PLATFORM_UI-INSIGHTS_CHROME
*/

// Timeout constants
const PAGE_LOAD_TIMEOUT = 60000; // Time to wait for initial page load
const FEEDBACK_SUBMISSION_TIMEOUT = 10000; // Time to wait for feedback submission to complete

test.describe('Feedback - Help Panel', () => {
test.beforeEach(async ({ page }) => {
// Block trustarc cookie prompts
await disableCookiePrompt(page);

// Navigate to home page - authentication state is already loaded from global setup
await page.goto('/', { waitUntil: 'load', timeout: PAGE_LOAD_TIMEOUT });

// Wait for chrome header to be fully loaded
await expect(page.getByText('Hi,')).toBeVisible();
});

test('should open feedback form, test navigation, and submit successfully', async ({ page }) => {
// Step 1: Click help button to open help panel
await page.getByLabel('Toggle help panel').click();

// Step 2: Wait for help panel to load
const helpPanelTitle = page.locator('[data-ouia-component-id="help-panel-title"]');
await expect(helpPanelTitle).toBeVisible();

// Step 3: Wait for subtabs to be visible and click "Feedback" subtab
const feedbackTab = page.locator('[data-ouia-component-id="help-panel-subtab-feedback"]');
await expect(feedbackTab).toBeVisible();
await feedbackTab.click();

// Step 4: Verify we're on the feedback home page
const feedbackHomeTitle = page.locator('[data-ouia-component-id="feedback-home-title"]');
await expect(feedbackHomeTitle).toBeVisible();

// Step 5: Test Back button navigation flow
// Open form
await page.getByText('Share general feedback').click();
const feedbackTextarea = page.locator('#feedback-description-text');
await expect(feedbackTextarea).toBeVisible();

// Click Back and verify return to home
await page.getByRole('button', { name: 'Back', exact: true }).click();
await expect(feedbackHomeTitle).toBeVisible();

// Step 6: Test submission flow (restart from feedback home)
// Open form again
await page.getByText('Share general feedback').click();
await expect(feedbackTextarea).toBeVisible();

// Fill in feedback with random text
const randomText = `AutoTest-${Math.random().toString(36).substring(2, 18)}`;
await feedbackTextarea.fill(`Testing insights feedback submission via Playwright automation. Random ID: ${randomText}`);

// Submit the feedback
const submitButton = page.getByRole('button', { name: /submit/i });
await submitButton.click();

// Step 7: Verify success message is displayed
await expect(page.getByText(/feedback shared successfully/i)).toBeVisible({ timeout: FEEDBACK_SUBMISSION_TIMEOUT });
await expect(page.getByText(/thank you/i)).toBeVisible();

// Step 8: Verify success state shows "Share more feedback" option
await expect(page.getByRole('button', { name: /share more feedback/i })).toBeVisible();

// Note: Actual JIRA ticket verification is not performed in this automated test.
// The feedback creates a ticket in https://issues.redhat.com/projects/CRCFEEDBK/issues/
// Manual verification may be needed to confirm ticket creation with correct labels:
// - learning-resources
// - help-panel-feedback
});
});
142 changes: 142 additions & 0 deletions playwright/support-case.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { test, expect } from '@playwright/test';
import { disableCookiePrompt } from './test-utils';

/**
* Support Case Tests
*
* Migrated from IQE: iqe_platform_ui/tests/test_support_case.py
*
* These tests verify that support case functionality is accessible from the help panel:
* - "Open a support case" button appears in the help menu
* - Clicking the button opens the Red Hat Customer Portal support case page
*
* TODO: Test #3 (test_support_case_from_apps) - Not yet migrated
* This test verifies that support case data is pre-filled correctly when opened from
* different apps. It requires:
* - Complex setup with actual support cases created via API
* - Cross-domain interaction with Customer Portal
* - Authentication on the external portal to validate pre-filled data
* - May be better suited for insights-chrome repository or separate E2E suite
*
* Requirements:
* - PLATFORM_UI-INSIGHTS_CHROME
* - PLATFORM_UI-SUPPORT_CASES
*/

// Timeout constants
const SUPPORT_API_LOAD_TIMEOUT = 15000; // Time to wait for support cases API to load

test.describe('Support Case - Help Panel', () => {
test.beforeEach(async ({ page }) => {
// Block trustarc cookie prompts
await disableCookiePrompt(page);

// Navigate to home page - authentication state is already loaded from global setup
await page.goto('/', { waitUntil: 'load', timeout: 60000 });

// Wait for chrome header to be fully loaded
await expect(page.getByText('Hi,')).toBeVisible();
});

test('should display "Open a support case" link in help panel', async ({ page }) => {
// Step 1: Click help button to open help panel
await page.getByLabel('Toggle help panel').click();

// Step 2: Wait for help panel to load
const helpPanelTitle = page.locator('[data-ouia-component-id="help-panel-title"]');
await expect(helpPanelTitle).toBeVisible();

// Step 3: Click on "My support cases" tab
const supportTab = page.locator('[data-ouia-component-id="help-panel-subtab-support"]');
await supportTab.click();

// Step 4: Wait for the support panel to finish loading
// The panel shows a skeleton loader while fetching support cases from API
// Wait for either empty state or table to appear (skeleton disappears)
const emptyState = page.locator('[data-ouia-component-id="help-panel-support-empty-state"]');
const supportTable = page.locator('[data-ouia-component-id="help-panel-support-cases-table"]');
await expect(emptyState.or(supportTable)).toBeVisible({ timeout: SUPPORT_API_LOAD_TIMEOUT });

// Step 5: The "Open a support case" button/link should now be visible
await expect(page.getByText(/open a support case/i)).toBeVisible();
Comment on lines +56 to +61
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

State-dependent CTA assumption makes these tests nondeterministic.

After Line 58 / Line 81 you allow either state, but Line 61 and Line 87 still assume "Open a support case" exists. In src/components/HelpPanel/HelpPanelTabs/SupportPanel.tsx:153-236, that CTA is rendered only for empty-state. Accounts with open cases will fail these tests even when behavior is correct.

Suggested fix
@@
-    await expect(emptyState.or(supportTable)).toBeVisible({ timeout: SUPPORT_API_LOAD_TIMEOUT });
-
-    // Step 5: The "Open a support case" button/link should now be visible
-    await expect(page.getByText(/open a support case/i)).toBeVisible();
+    await expect(emptyState.or(supportTable)).toBeVisible({ timeout: SUPPORT_API_LOAD_TIMEOUT });
+    const openSupportCaseCta = page.locator('[data-ouia-component-id="help-panel-open-support-case-button"]');
+    if (await emptyState.isVisible()) {
+      await expect(openSupportCaseCta).toBeVisible();
+    } else {
+      await expect(supportTable).toBeVisible();
+      test.skip('Open a support case CTA is only present in empty-state view.');
+    }
@@
-    await expect(emptyState.or(supportTable)).toBeVisible({ timeout: SUPPORT_API_LOAD_TIMEOUT });
+    await expect(emptyState.or(supportTable)).toBeVisible({ timeout: SUPPORT_API_LOAD_TIMEOUT });
+    const openSupportCaseCta = page.locator('[data-ouia-component-id="help-panel-open-support-case-button"]');
+    if (!(await emptyState.isVisible())) {
+      test.skip('Open a support case CTA is only present in empty-state view.');
+    }
@@
-    await page.getByText(/open a support case/i).click();
+    await openSupportCaseCta.click();

Also applies to: 79-88

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@playwright/support-case.spec.ts` around lines 56 - 61, The test assumes the
"Open a support case" CTA is always present but the SupportPanel renders that
CTA only in empty-state; update the spec to branch on which locator is visible:
use the existing emptyState and supportTable locators (emptyState, supportTable)
to await visibility, then if emptyState.isVisible() assert page.getByText(/open
a support case/i).toBeVisible(), else assert the CTA is not present or instead
assert the supportTable has expected rows; reference the SupportPanel component
behavior (src/components/HelpPanel/HelpPanelTabs/SupportPanel) when adding the
conditional assertion so tests are deterministic for accounts with open cases.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed. The test account will not have any open cases because it is an isolated account used for this automation only.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@catastrophe-brandon, understood — thanks for the context! Since the automation uses a dedicated, isolated account with no existing support cases, the empty-state is guaranteed and the CTA will always be present. That makes the current assertion perfectly deterministic for this setup.


📝 Learnings were identified and not saved (knowledge base disabled). Enable

});

test('should open Customer Portal when clicking "Open a support case" link', async ({ page, context }) => {
// Step 1: Click help button to open help panel
await page.getByLabel('Toggle help panel').click();

// Step 2: Wait for help panel to load
const helpPanelTitle = page.locator('[data-ouia-component-id="help-panel-title"]');
await expect(helpPanelTitle).toBeVisible();

// Step 3: Click on "My support cases" tab
const supportTab = page.locator('[data-ouia-component-id="help-panel-subtab-support"]');
await supportTab.click();

// Step 4: Wait for the support panel to finish loading
// The panel shows a skeleton loader while fetching support cases from API
// Wait for either empty state or table to appear (skeleton disappears)
const emptyState = page.locator('[data-ouia-component-id="help-panel-support-empty-state"]');
const supportTable = page.locator('[data-ouia-component-id="help-panel-support-cases-table"]');
await expect(emptyState.or(supportTable)).toBeVisible({ timeout: SUPPORT_API_LOAD_TIMEOUT });

// Step 5: Set up listener for new page/tab before clicking
const pagePromise = context.waitForEvent('page');

// Step 6: Click the "Open a support case" button/link
await page.getByText(/open a support case/i).click();

// Step 7: Wait for new page to open and verify it navigates to Red Hat Customer Portal
const newPage = await pagePromise;

// Wait for navigation to Red Hat Customer Portal (page starts at about:blank)
await newPage.waitForURL(/access\.redhat\.com/);

// Verify the destination hostname (we can't validate page content due to auth requirements)
const url = new URL(newPage.url());
expect(url.hostname).toBe('access.redhat.com');

// Clean up - close the new tab
await newPage.close();
});

test('should display support cases table when user has open cases', async ({ page }) => {
// Step 1: Click help button to open help panel
await page.getByLabel('Toggle help panel').click();

// Step 2: Wait for help panel to load
const helpPanelTitle = page.locator('[data-ouia-component-id="help-panel-title"]');
await expect(helpPanelTitle).toBeVisible();

// Step 3: Click on "My support cases" tab
const supportTab = page.locator('[data-ouia-component-id="help-panel-subtab-support"]');
await supportTab.click();

// Step 4: Wait for support panel to load and check if user has support cases
const supportTable = page.locator('[data-ouia-component-id="help-panel-support-cases-table"]');
const emptyState = page.locator('[data-ouia-component-id="help-panel-support-empty-state"]');

// Wait for either the table or empty state to appear (let it fail if timeout)
await expect(supportTable.or(emptyState)).toBeVisible({ timeout: SUPPORT_API_LOAD_TIMEOUT });

// Check if empty state is visible (user has no cases)
const emptyVisible = await emptyState.isVisible().catch(() => false);
if (emptyVisible) {
// User has no cases, skip this test
test.skip();
return;
}

// Verify table is visible
await expect(supportTable).toBeVisible();

// Verify pagination is present
const pagination = page.locator('[data-ouia-component-id="help-panel-support-pagination"]');
await expect(pagination).toBeVisible();

// Verify table has at least one row (case)
const tableRows = supportTable.locator('tbody tr');
const rowCount = await tableRows.count();
expect(rowCount).toBeGreaterThan(0);
});
});
Loading