Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
"clean": "yarn workspaces foreach --all --topological --parallel run clean && rm -rf node_modules",
"clean:dist": "yarn workspaces foreach --all --topological --parallel run clean:dist",
"test:unit": "yarn run test:tooling && yarn run test:cc-widgets && yarn run test:meetings-widget",
"test:e2e": "yarn playwright test",
"test:e2e:cc": "yarn workspace @webex/cc-widgets run test:e2e",
"test:e2e:meetings": "yarn workspace @webex/widgets run test:e2e",
Comment on lines +57 to +58

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the documented root E2E command

Replacing test:e2e with only the two suffixed scripts leaves no root script named test:e2e, while the modified Playwright README still uses yarn test:e2e for every all-suite, single-suite, project, UI, debug, and headed invocation. Those documented local commands now fail during script resolution before Playwright starts; retain a compatible alias or update the documented callers to use test:e2e:cc.

AGENTS.md reference: AGENTS.md:L78-L78

Useful? React with 👍 / 👎.

"test:styles": "yarn workspaces foreach --all --exclude webex-widgets run test:styles",
"test:tooling": "NODE_ENV=test jest --coverage",
"test:cc-widgets": "yarn workspaces foreach --all --exclude webex-widgets --exclude samples-cc-wc-app --exclude samples-cc-react-app run test:unit",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
| Doc kind | Module spec |
| Coverage score | Pending coverage assessment |
| Generated from | `module-spec` @ SDLC template library `0.1.0-draft` |
| generated_by / approved_by / updated_at | generated_by `ai-assistant feature work` / approved_by `pending` / updated_at `2026-07-29` |
| generated_by / approved_by / updated_at | generated_by `ai-assistant feature work` / approved_by `pending` / updated_at `2026-08-04` |
| Validation status | not-run |

## Evidence Rules
Expand Down Expand Up @@ -204,6 +204,15 @@ views and the ErrorBoundary path. `tests/ai-assistant/feedback.tsx` covers like/
and the missing-`adaptiveCardId` warning. UI-level rendering (spinner, error text,
snapshots) is covered in `cc-components/tests/components/AIAssistant/`.

Playwright coverage lives in `playwright/tests/real-time-assist-test.spec.ts` and runs in the SET_4
call suite. It deterministically controls the SDK request and feedback promises, injects
`SUGGESTED_RESPONSE` payloads through `store.handleRealTimeAssist`, and verifies the complete visible
state sequence: chrome actions; no-task and feature-disabled gates; empty, requesting, failure/retry,
listening, and ready states; context requests; ordered responses; Adaptive Card fallback and feedback;
close/reopen preservation; and task-removal cleanup. A final test restores the SDK methods and waits for
a live backend suggestion so deterministic rendering coverage does not replace the integration smoke
check.

## Traceability
- Repo architecture: `../../../../ai-docs/ARCHITECTURE.md` · Registry: `../../../../ai-docs/SPEC_INDEX.md`
- Coverage state & contracts baseline: `.sdd/manifest.json`
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ const RealTimeTranscriptComponent: React.FC<RealTimeTranscriptComponentProps> =
) : null}
</Text>
) : null}
<div className="real-time-transcript__item" data-testid="real-time-transcript:item">
<div
className="real-time-transcript__item"
data-testid="real-time-transcript:item"
data-speaker-role={entry.isCustomer ? 'customer' : 'agent'}
Comment on lines +51 to +52

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Document the new transcript speaker-role contract

The new E2E helpers depend on data-speaker-role as a stable selector, making this externally observable markup part of the transcript component's behavior, but the commit leaves packages/contact-center/cc-components/ai-docs/cc-components-spec.md—especially CC-COMPONENTS-R-011—unchanged. Document the attribute and its agent/customer mapping in the module spec in this change so future component refactors do not silently invalidate the E2E contract.

AGENTS.md reference: AGENTS.md:L68-L68

Useful? React with 👍 / 👎.

>
<div className="real-time-transcript__avatar-wrap">
<Avatar
className="real-time-transcript__avatar-fallback"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ exports[`RealTimeTranscriptComponent snapshots matches snapshot with transcript
>
<div
class="real-time-transcript__item"
data-speaker-role="agent"
data-testid="real-time-transcript:item"
>
<div
Expand Down Expand Up @@ -50,6 +51,7 @@ exports[`RealTimeTranscriptComponent snapshots matches snapshot with transcript
</div>
<div
class="real-time-transcript__item"
data-speaker-role="customer"
data-testid="real-time-transcript:item"
>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ describe('RealTimeTranscriptComponent', () => {
const messages = screen.getAllByTestId('real-time-transcript:item');
expect(messages).toHaveLength(2);
expect(messages[0]).toHaveTextContent('Agent message');
expect(messages[0]).toHaveAttribute('data-speaker-role', 'agent');
expect(messages[1]).toHaveTextContent('Customer message');
expect(messages[1]).toHaveAttribute('data-speaker-role', 'customer');
});

it('renders transcript event inline with timestamp', () => {
Expand Down
1 change: 1 addition & 0 deletions packages/contact-center/cc-widgets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"build:src": "yarn run clean:dist && webpack",
"build:watch": "webpack --watch",
"test:unit": "NODE_ENV=test jest --coverage",
"test:e2e": "yarn run -T playwright test --config ../../../playwright.config.ts",
"test:styles": "eslint",
"deploy:npm": "yarn npm publish"
},
Expand Down
74 changes: 54 additions & 20 deletions playwright/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,58 @@ playwright/
- ✅ Positions browser windows automatically
- ✅ Maps test suites to user sets

| Set | Focus | Port | Suite File |
| --------- | ---------------------------------- | ---- | -------------------------------------------- |
| **SET_1** | Digital incoming tasks & controls | 9221 | `digital-incoming-task-tests.spec.ts` |
| **SET_2** | Task lists & multi-session | 9222 | `task-list-multi-session-tests.spec.ts` |
| **SET_3** | Authentication & user management | 9223 | `station-login-user-state-tests.spec.ts` |
| **SET_4** | Task controls & combinations | 9224 | `basic-advanced-task-controls-tests.spec.ts` |
| **SET_5** | Advanced task operations | 9225 | `advanced-task-controls-tests.spec.ts` |
| **SET_6** | Dial number scenarios | 9226 | `dial-number-tests.spec.ts` |
| **SET_7** | Multiparty conference (team 25-28) | 9227 | `multiparty-conference-set-7-tests.spec.ts` |
| **SET_8** | Multiparty conference (team 29-32) | 9228 | `multiparty-conference-set-8-tests.spec.ts` |
| **SET_9** | Multiparty conference (team 33-36) | 9229 | `multiparty-conference-set-9-tests.spec.ts` |
| Set | Focus | Port | Suite File |
| ---------- | ----------------------------------- | ---- | -------------------------------------------- |
| **SET_1** | Digital incoming tasks & controls | 9221 | `digital-incoming-task-tests.spec.ts` |
| **SET_2** | Task lists & multi-session | 9222 | `task-list-multi-session-tests.spec.ts` |
| **SET_3** | Authentication & user management | 9223 | `station-login-user-state-tests.spec.ts` |
| **SET_4** | Task controls & combinations | 9224 | `basic-advanced-task-controls-tests.spec.ts` |
| **SET_5** | Advanced task operations | 9225 | `advanced-task-controls-tests.spec.ts` |
| **SET_6** | Dial number scenarios | 9226 | `dial-number-tests.spec.ts` |
| **SET_7** | Multiparty conference (team 25-28) | 9227 | `multiparty-conference-set-7-tests.spec.ts` |
| **SET_8** | Multiparty conference (team 29-32) | 9228 | `multiparty-conference-set-8-tests.spec.ts` |
| **SET_9** | Multiparty conference (team 33-36) | 9229 | `multiparty-conference-set-9-tests.spec.ts` |

### Where to Add New Tests?

| Test Type | Use Set | Why |
| ---------------------------- | --------- | --------------------------- |
| Digital channels tasks | SET_1 | Digital channels configured |
| Task list operations | SET_2 | Task list focus |
| Authentication/User states | SET_3 | User management |
| Basic/Advanced task controls | SET_4 | Task control operations |
| Complex advanced scenarios | SET_5 | Advanced operations |
| Dial number scenarios | SET_6 | Dial number flows |
| Multiparty conference | SET_7/8/9 | 4-agent conference coverage |
| Test Type | Use Set | Why |
| ----------------------------------- | --------- | --------------------------------------------------- |
| Digital channels tasks | SET_1 | Digital channels configured |
| Task list operations | SET_2 | Task list focus |
| Authentication/User states | SET_3 | User management |
| Basic/Advanced task controls | SET_4 | Task control operations; single agent + caller call |
| Complex advanced scenarios | SET_5 | Advanced operations |
| Dial number scenarios | SET_6 | Dial number flows |
| Multiparty conference | SET_7/8/9 | 4-agent conference coverage |
| AI Assistant / Real-Time Transcript | SET_4 | Live call required for both; reuses SET_4's agent |

> **Note on AI Assistant / Real-Time Transcript coverage:** these tests are bundled into
> `SET_4`'s suite, `basic-advanced-task-controls-tests.spec.ts`, and reuse its
> already-provisioned agent (`user21`) plus caller. Both features retain a lightweight
> live-backend smoke check. Precise UI behavior is tested deterministically by driving
> the same sample-app store surfaces used by SDK events: Real Time Assist controls the
> SDK request/feedback promises and injects `SUGGESTED_RESPONSE` payloads through
> `store.handleRealTimeAssist`; Real-Time Transcript injects
> `REAL_TIME_TRANSCRIPTION` payloads through `store.handleRealtimeTranscription`.
> This split verifies the real integration path without making every rendering and
> transition assertion depend on non-deterministic AI/speech timing.

### Real Time Assist scenario coverage

`playwright/tests/real-time-assist-test.spec.ts` runs serially because it validates one
continuous interaction lifecycle. It covers:

- launcher, open, minimize, restore, fullscreen, exit-fullscreen, close, and reopen;
- no-interaction, feature-disabled, active/request, pending, error, retry, listening,
ready, and task-ended render states;
- `getRealTimeAssistance` payloads, pending-request duplicate prevention, context
submission, user-message rendering, and subsequent suggestions;
- deterministic `SUGGESTED_RESPONSE` rendering, chronological ordering, Adaptive Card
actions, and the plain-text fallback path;
- feedback API payloads and the rule that like/dislike selection changes only after
backend success; and
- active-session preservation across close/reopen, interaction cleanup, and one final
live SDK/backend suggestion smoke check.

## Multiparty Conference Consolidation

Expand All @@ -79,6 +108,10 @@ To reduce runtime and repeated call initialization, conference scenarios are con

## 🧪 Adding New Tests

The OAuth setup project and all user-set projects run against the installed
Google Chrome channel. This keeps browser selection consistent across setup and
feature tests and avoids requiring a separate bundled Chromium revision.

### 1. Create Test File (in `tests/` folder)

```typescript
Expand Down Expand Up @@ -193,6 +226,7 @@ Create `.env` file in project root:
```env
PW_CHAT_URL=https://your-chat-url
PW_SANDBOX=your-sandbox-name
PW_SANDBOX_PASSWORD=your-test-agent-password
PW_ENTRY_POINT1=entry-point-1
PW_ENTRY_POINT2=entry-point-2
# ... PW_ENTRY_POINT3 ... PW_ENTRY_POINT9
Expand Down
Loading
Loading