Skip to content

test(calling): added playwright tests for call settings#5012

Open
vivekv1504 wants to merge 5 commits into
webex:nextfrom
vivekv1504:callingSDK-callsettings
Open

test(calling): added playwright tests for call settings#5012
vivekv1504 wants to merge 5 commits into
webex:nextfrom
vivekv1504:callingSDK-callsettings

Conversation

@vivekv1504

@vivekv1504 vivekv1504 commented May 29, 2026

Copy link
Copy Markdown
Contributor

COMPLETES #< https://jira-eng-sjc12.cisco.com/jira/browse/CAI-7878 >

This pull request addresses

The Calling SDK CallSettingsClient APIs (Do Not Disturb, Call Forwarding, Voicemail, and Call Waiting) did not have end-to-end Playwright coverage against the calling sample app. Without automated tests, regressions in settings fetch/save, UI wiring, or live call behavior (e.g. DND blocking incoming calls, call forwarding routing) could go unnoticed.

This PR adds a dedicated SET_CALL_SETTINGS Playwright project and a full E2E suite that exercises these flows through the sample app UI and validates real call behavior with multiple registered users.

by making the following changes

Playwright test infrastructure

  • Added SET_CALL_SETTINGS user set in test-data.ts with three accounts:
    • USER_3 — settings owner / callee
    • USER_2 — primary caller
    • USER_1 — second caller (for multi-user scenarios)
  • Registered SET_CALL_SETTINGS - PROD and SET_CALL_SETTINGS - INT projects in playwright.config.ts (with OAuth dependencies).
  • Added suite entry point: playwright/suites/set-call-settings.spec.ts.

Reusable test utilities (utils/call-settings.ts)

  • loadSettings() — clicks “Get Settings” and waits for both callForwarding and voicemail GET responses plus DND UI settle (avoids saving CF/VM before server state is loaded).
  • DND helpers  clickDnd(), ensureDndState() with PUT wait + expect.poll() to handle eventual consistency between write and read.
  • Call Forward helpers  setCallForwardAlways/Busy/NoAnswer/NotReachable() and saveCfSettings() with PUT response waits.
  • Voicemail helpers  setVoicemailSendAllCalls/BusyCalls/UnansweredCalls() and saveVoicemailSettings().

Selectors (constants/selectors.ts)

  • Added call-settings selectors for DND, Call Waiting, Call Forward, and Voicemail forms.
  • Scoped selectors to #callForwardForm and #voicemailForm to avoid duplicate ID collisions in the sample app.

UI tests (callSettingsTests) — single user, serial

Test ID | Coverage -- | -- CS-GET-001 | Get Settings — all UI fields settle and become enabled CS-DND-002 | DND enable/disable round-trip CS-CF-003–006 | Call Forward Always, Busy, No Answer (+ rings), Not Reachable round-trips CS-CFA-007 | Get Call Forward Always by directory number CS-ERR-008 | DND PUT 500 — button text reverts CS-VM-009–015 | Voicemail form load, toggles, numberOfRings, MWI, enabled, email notification, email copy

Each live-call test resets settings in beforeAll / finally blocks and uses INCOMING_CALL_ANSWER_BTN to assert whether line:incoming_call fired.

Reliability fixes

  • Improved DND toggle handling to poll server state after PUT instead of relying on immediate UI updates.
  • Tests restore original settings after each case to avoid polluting shared test accounts.

Sample app

  • Minor fix in docs/samples/calling/index.html: corrected voicemail “When not answered” rings input ID (vmNotAnsweredRings).

Screenshot 2026-05-29 at 13 04 00 Screenshot 2026-05-29 at 13 04 26

Change Type

  • Bug fix (non-breaking change which fixes an issue)
  • [ x] New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Tooling change
  • Internal code refactor

The following scenarios were tested

< ENUMERATE TESTS PERFORMED, WHETHER MANUAL OR AUTOMATED >

The GAI Coding Policy And Copyright Annotation Best Practices

  • GAI was not used (or, no additional notation is required)
  • Code was generated entirely by GAI
  • GAI was used to create a draft that was subsequently customized or modified
  • Coder created a draft manually that was non-substantively modified by GAI (e.g., refactoring was performed by GAI on manually written code)
  • Tool used for AI assistance (GitHub Copilot / Other - specify)
    • Github Copilot
    • Other - Cursor
  • This PR is related to
    • Feature
    • Defect fix
    • Tech Debt
    • Automation

I certified that

  • I have read and followed contributing guidelines
  • I discussed changes with code owners prior to submitting this pull request
  • I have not skipped any automated checks
  • All existing and new tests passed
  • I have updated the documentation accordingly

Make sure to have followed the contributing guidelines before submitting.

@vivekv1504 vivekv1504 requested a review from a team as a code owner May 29, 2026 16:51

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1d43739d40

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/calling/playwright.config.ts Outdated
// Single-user Call Settings tests
{
name: 'SET_CALL_SETTINGS - PROD',
dependencies: ['OAuth - PROD'],

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 Serialize call-settings projects with shared accounts

SET_CALL_SETTINGS uses USER_1, USER_2, and USER_3, but this project only depends on OAuth, so Playwright can run it in parallel with the registration projects and SET_CALL_TRANSFER_CONSULT, which use the same accounts. test-data.ts documents that the same Webex account must never be active in two sessions simultaneously and that dependencies are how shared accounts are ordered; with this dependency, these new tests can deregister or mutate settings while the other projects are running, making the E2E suite flaky.

Useful? React with 👍 / 👎.

Comment on lines +151 to +153
// Restore
if (originalChecked) {
await setCallForwardAlways(page, true, cfDestination);

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 Restore the original forwarding destination

When CF Always was already enabled before the test, the cleanup re-enables it with cfDestination (USER_2) instead of the destination that was loaded from the account. On real PROD/INT test accounts this leaves the user's call-forwarding target permanently changed after the test; capture the original destination/ring values before overwriting them and restore those exact values.

Useful? React with 👍 / 👎.

@vivekv1504 vivekv1504 added the validated If the pull request is validated for automation. label May 29, 2026
@aws-amplify-us-east-2

Copy link
Copy Markdown

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-5012.d3m3l2kee0btzx.amplifyapp.com

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f8cf4e3bb1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 131 to 132
testSuite: 'set-call-settings.spec.ts',
// Single-user Contacts supplementary service E2E tests

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 Close the SET_CALL_SETTINGS entry

SET_CALL_SETTINGS never closes before the SET_CONTACTS key starts, so USER_SETS is syntactically malformed and importing packages/calling/playwright.config.ts fails before Playwright can discover or run any suite. Add the missing }, after this entry so the existing SET_CONTACTS project remains a sibling instead of being parsed inside it.

Useful? React with 👍 / 👎.

Comment on lines +637 to +639
// USER_4's number is a valid system number with no active registration here,
// so calls forwarded to it go to voicemail rather than looping back.
cfDestination = getPhoneNumber('USER_4');

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 Serialize the USER_4 forwarding target

In PROD runs, this suite forwards live calls to USER_4, but playwright.config.ts lets SET_CALL_SETTINGS - PROD and SET_CALL - PROD both depend only on OAuth while SET_CALL actively registers USER_4/USER_5. When those projects overlap, the forwarded calls can ring USER_4's active SET_CALL session instead of going to voicemail, breaking the assumption in the comment and making both suites flaky; either declare/serialize this USER_4 usage or use a truly unused destination.

Useful? React with 👍 / 👎.

Comment on lines +647 to +655
await loadSettings(calleePage);
await setCallForwardAlways(calleePage, false);
await setCallForwardBusy(calleePage, false);
await setCallForwardNoAnswer(calleePage, false);
await setCallForwardNotReachable(calleePage, false);
await ensureDndState(calleePage, 'DND Disabled');
await setVoicemailSendAllCalls(calleePage, false);
await setVoicemailSendBusyCalls(calleePage, false);
await setVoicemailSendUnansweredCalls(calleePage, false);

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 callee's original settings

When these live-call tests start on an account that already has DND, call forwarding, or voicemail forwarding enabled, the setup unconditionally disables every setting and the later cleanup/finally blocks leave them disabled rather than restoring the original values. Because these run against shared PROD/INT test accounts, a passing or failed run can permanently change the account baseline and affect later suites; snapshot the loaded settings before this reset and restore them in afterAll.

Useful? React with 👍 / 👎.

@eigengravy eigengravy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

E2E test review — there's a parse error that blocks the entire suite, an account isolation violation, and several test logic gaps. Details inline.

SET_CALL_SETTINGS: {
name: 'SET_CALL_SETTINGS',
accounts: ['USER_3', 'USER_2', 'USER_1'],
testSuite: 'set-call-settings.spec.ts',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

CRITICAL: Missing closing }, — this file won't parse

The SET_CALL_SETTINGS object is missing its closing brace+comma. Playwright test discovery will fail immediately with a syntax error.

  SET_CALL_SETTINGS: {
    name: 'SET_CALL_SETTINGS',
    accounts: ['USER_3', 'USER_2', 'USER_1'],
    testSuite: 'set-call-settings.spec.ts',
+ },
  // Single-user Contacts supplementary service E2E tests
  SET_CONTACTS: {

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.

Done chnages applied ,rebase the branch and appiled the changes

use: browserOptions[PW_BROWSER],
},
{
name: 'SET_CALL_SETTINGS - INT',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Account isolation violation: SET_CALL_SETTINGS shares USER_1/2/3 with registration tests

SET_CALL_SETTINGS uses accounts USER_1, USER_2, and USER_3 but only depends on OAuth - PROD. Since SET_REGISTRATION_1/2/3 also depend only on OAuth and use these same accounts, Playwright can schedule them concurrently — violating the constraint at the top of test-data.ts:

the same Webex account must NEVER be active in two browser sessions simultaneously

This needs dependencies: ['SET_REGISTRATION_1 - PROD', 'SET_REGISTRATION_2 - PROD', 'SET_REGISTRATION_3 - PROD'] at minimum, or should wait until after SET_CALL (which already serializes through the registration projects).

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.

added dependencies on SET_REGISTRATION_1/2/3 and SET_CALL_TRANSFER_CONSULT for both PROD and INT so SET_CALL_SETTINGS won’t run concurrently with other suites using USER_1/2/3.

// Allow the CF setting to propagate to the server before placing the call.
await calleePage.waitForTimeout(5000);

try {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Test logic gap: no caller-side verification that the call was actually placed

CS-CALL-101 (and CS-CALL-102 below) only asserts the callee's answer button stays disabled. But if makeCall() silently fails (network error, invalid number, SDK exception), no call is created and the callee never rings — the test still passes.

You need a caller-side assertion to confirm the outbound call was actually established. For example, wait for the caller's call-state indicator to show an active/ringing call before starting the observation window on the callee side.

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.

Added waitForCallerOutboundCall() after makeCall() in CS-CALL-101 and CS-CALL-102. It waits for the caller’s SDK to report an active outbound call via getActiveCalls() before asserting the callee doesn’t ring, so the test fails if the dial never happened.


// Reload and verify the setting was persisted on the server.
await loadSettings(calleePage);
await expect(calleePage.locator(CALLING_SELECTORS.CF_BUSY_CB)).toBeChecked({

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Incomplete test: CS-CALL-103 never actually tests CF Busy forwarding

The test name says "CF When Busy" but it only verifies:

  1. The setting persists after reload
  2. The first call rings normally

It never:

  • Answers the first call (to make the callee busy)
  • Places a second call from secondCallerPage (USER_1)
  • Verifies the second call gets forwarded instead of ringing the callee

As written, this test passes even if CF Busy forwarding is completely broken. The title should either be renamed to reflect what it actually tests ("CF Busy setting persists and doesn't affect non-busy calls"), or the test should be completed to exercise the actual busy-forward path.

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.

added waitForCallerOutboundCall() on CS-CALL-101/102/104/105/106; implemented CS-CALL-103 (answer first call, second call while busy, call-waiting-aware); hardened CS-CALL-104/106 with setting reload/verify. Full SET_CALL_SETTINGS - PROD suite passes locally.


// Enable the checkbox so the email input is accessible.
if (!originalChecked) {
await page.locator(CALLING_SELECTORS.VM_NOTIF_EMAIL_CB).check({timeout: AWAIT_TIMEOUT});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Incomplete restoration: if checkbox was originally ON, the test email is left in the account

The restoration block only unchecks if the checkbox was originally off:

if (!originalChecked) {
  await page.locator(...).uncheck(...);
}
await saveVoicemailSettings(page);

If the checkbox was already enabled, the test overwrites the real email with autotest-notification@example.com and never restores it. The account is left with a test email address as the configured notification destination.

Fix: capture originalEmail before the test, and always restore both the checkbox state and the email value:

const originalEmail = await page.locator(CALLING_SELECTORS.VM_NOTIF_EMAIL_ID).inputValue();
// ... test ...
// Restore:
if (originalChecked) {
  await page.locator(CALLING_SELECTORS.VM_NOTIF_EMAIL_ID).fill(originalEmail || '');
} else {
  await page.locator(CALLING_SELECTORS.VM_NOTIF_EMAIL_CB).uncheck(...);
}

Same issue exists in CS-VM-015 below.

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.

restoration now captures originalEmail via inputValue() before the test overwrites it. If the checkbox was originally on, we restore the prior email and save; if it was off, we uncheck and save. Applied the same fix to CS-VM-015.

@vivekv1504 vivekv1504 force-pushed the callingSDK-callsettings branch from f8cf4e3 to e68b9a7 Compare June 4, 2026 07:14

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e68b9a7cc4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +527 to +529
const testEmail = 'autotest-notification@example.com';
await page.locator(CALLING_SELECTORS.VM_NOTIF_EMAIL_ID).fill(testEmail, {force: true});
await saveVoicemailSettings(page);

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 Restore original voicemail email destinations

When the account already has email notifications enabled, this overwrites the saved destination with autotest-notification@example.com and the cleanup only preserves the checkbox state, so shared PROD/INT test accounts are left with a different voicemail notification address after the suite. Snapshot the original email value before filling the test address and restore it when originalChecked is true; the email-copy test below has the same issue.

Useful? React with 👍 / 👎.

Comment on lines +356 to +358
const targetRings = '4';
await page.locator(CALLING_SELECTORS.VM_UNANSWERED_RINGS).fill(targetRings, {force: true});
await saveVoicemailSettings(page);

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 Restore the original voicemail ring count

When sendUnansweredCalls is already enabled on the shared account, this changes numberOfRings to 4 and never restores the previous value because the cleanup only unchecks the box when it was originally off. A passing run can therefore permanently alter the voicemail timeout for later suites or manual use; capture the original ring count and write it back when the setting was originally enabled.

Useful? React with 👍 / 👎.

@Shreyas281299 Shreyas281299 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Submitting accidental empty pending review.

Comment thread packages/calling/playwright.config.ts Outdated
Comment on lines +158 to +172
// 3-user transfer tests — waits for 2-user (shared USER_4+USER_5)
// {
// name: 'SET_3USER - PROD',
// dependencies: ['SET_2USER - PROD'],
// testDir: './playwright/suites',
// testMatch: USER_SETS.SET_3USER.testSuite,
// use: browserOptions[PW_BROWSER],
// },
// {
// name: 'SET_3USER - INT',
// dependencies: ['SET_2USER - INT'],
// testDir: './playwright/suites',
// testMatch: USER_SETS.SET_3USER.testSuite,
// use: {...browserOptions[PW_BROWSER], testEnv: 'int'} as any,
// },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please remove these commented lines

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.

Done! Removed commented lines

@Shreyas281299 Shreyas281299 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Posting inline findings from /tmp/pr5012-review.md.

},
// Single-user Call Settings tests
{
name: 'SET_CALL_SETTINGS - PROD',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SET_CALL_SETTINGS currently reuses USER_1/USER_2/USER_3, which are also used by SET_REGISTRATION_1/2/3. Since these projects only depend on OAuth and run in parallel, this violates the single-active-session rule in test-data and creates account-collision flakiness. Could we assign a dedicated user set to SET_CALL_SETTINGS (or add explicit project dependencies) so those sessions never overlap?

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.

SET_CALL_SETTINGS currently shares USER_1/2/3 with SET_REGISTRATION_* and SET_CALL_TRANSFER_CONSULT while only depending on OAuth, which breaks the single-active-session rule in test-data.ts. I’ll fix this in a follow-up by [adding project dependencies | assigning a dedicated user set] so those sessions never overlap.

// Allow the setting to propagate before placing the call.
await calleePage.waitForTimeout(5000);

try {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

cfDestination = getPhoneNumber('USER_4') can collide with SET_CALL - PROD, where USER_4 is actively registered in parallel. That means forwarded calls from CS-CALL-101 may ring in the SET_CALL suite and perturb both projects. Can we route CF tests to a destination number not owned by any concurrently registered test account?

const dest = page.locator(CALLING_SELECTORS.CF_ALWAYS_DEST);
const isChecked = await cb.isChecked();

if (enable && !isChecked) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In setCallForwardAlways (and similarly at the Busy/NoAnswer/NotReachable helpers), when enable === true and the toggle is already checked, we skip filling destination and still save. That can silently persist a stale number from previous state. Consider adding an enable && isChecked && destination branch to always refresh the destination before saveCfSettings.

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.

Fixed — added enable && isChecked && destination handling to all CF helpers so the destination is always refreshed before save when enabling with an explicit number.

test('CS-VM-012: Voicemail — MWI notification badge toggle saves and reloads correctly', async () => {
await loadSettings(page);
const original = await page.locator(CALLING_SELECTORS.VM_MWI_CB).isChecked();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

page.unroute('**/features/doNotDisturb*', routeHandler) is currently outside a finally block. If an assertion throws before the end, the route stub can leak and affect retries/subsequent tests in the same page context. Could we wrap the route setup in try/finally and always unroute in finally?

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.

Wrapped the DND route stub in try/finally and pass the same routeHandler to unroute so the stub is always removed, even when assertions fail.


if (original) {
await expect(page.locator(CALLING_SELECTORS.VM_UNANSWERED_CB)).not.toBeChecked({
timeout: OPERATION_TIMEOUT,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

expect(cfaDataElem).not.toBeEmpty() is too weak here because both success and error paths populate the element (callSetting or error), so this can pass on regressions. Can we assert a semantic value instead (e.g., expected destination substring or parsed JSON fields) to prove the call-forward update actually succeeded?

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.

Thanks — agreed that not.toBeEmpty() was too weak since both success (callSetting) and error paths populate #callforwardalways-data.

Updated CS-CFA-007 to assert on the network response instead: we wait for a successful GET callForwarding, then verify the response body includes callForwarding.always with a boolean enabled field. This ensures the lookup used valid API data rather than only checking that the element had any text (which could be an error string).

// 4. Enter password and click Sign In
await page.getByPlaceholder('Password').fill(password, {timeout: 15000});
await page
.locator('input#IDToken2[name="IDToken2"][type="password"]')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Switching to a strict input#IDToken2[name="IDToken2"][type="password"] selector improves specificity but removes the previous placeholder-based fallback. Since IdP attribute churn is common, can we keep this selector as primary and fall back to getByPlaceholder('Password') if it doesn't resolve?

@vivekv1504 vivekv1504 Jun 5, 2026

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.

restored the fallback. Password entry now uses input#IDToken2[name="IDToken2"][type="password"] as the primary locator and falls back to getByPlaceholder('Password') via .or() if the strict selector doesn’t resolve. This keeps specificity when the IdP markup is stable while still tolerating attribute churn.

CF_NO_ANSWER_DEST: '#notAnsweredDest',
CF_NOT_REACHABLE_CB: '#notReachableCb',
CF_NOT_REACHABLE_DEST: '#notReachableDest',
CF_DIRECTORY_NUMBER: '#directoryNumber',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

div#incomingsection #answer relies on the container tag name to disambiguate duplicate incomingsection IDs. If markup changes (e.g., fieldset -> div), this may become ambiguous and fail in strict mode. Would it be safer to fix duplicate IDs in sample HTML and keep selectors semantically unique?

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.

Addressed by removing duplicate IDs from the sample HTML and standardizing on INCOMING_ANSWER_BTN: '#incomingsection #answer'. No tag-based disambiguation needed anymore.

await setCallForwardNoAnswer(calleePage, true, cfDestination);
// Allow the setting to propagate before placing the call.
await calleePage.waitForTimeout(5000);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

secondCallerPage appears to be fully initialized but unused in callSettingsCallTests, while still adding setup cost and an extra registered account session. Is this context still required? If not, removing it may both reduce runtime and eliminate one source of account collision.

Comment thread packages/calling/playwright.config.ts Outdated
use: {...browserOptions[PW_BROWSER], testEnv: 'int'} as any,
},

// 3-user transfer tests — waits for 2-user (shared USER_4+USER_5)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Noting the commented SET_3USER block references identifiers/projects that don't exist (USER_SETS.SET_3USER, SET_2USER - PROD/INT). Could we either remove this stale block or update it to valid identifiers to avoid confusion for future maintainers?

@vivekv1504 vivekv1504 Jun 5, 2026

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.

Already removed the stale commented SET_3USER / SET_2USER block in the latest push — it was leftover from an older naming scheme. The live config now only uses SET_CALL and SET_CALL_TRANSFER_CONSULT

});
};

export const answerCall = async (page: Page): Promise<void> => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

waitForIncomingCall and answerCall now rely on different incoming-answer selectors (INCOMING_CALL_ANSWER_BTN vs INCOMING_ANSWER_BTN). That split can cause partial breakages if one locator changes independently. Can we standardize both flows on a single selector constant/invariant?

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.

Standardized on a single INCOMING_ANSWER_BTN constant. Both waitForIncomingCall and answerCall use it, and call-settings.ts was updated. Removed the duplicate incoming-call markup from the sample HTML so the selector is #incomingsection #answer without tag-based disambiguation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c3e809af98

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +21 to +22
// Wait for both forms to be populated from the server before returning.
await Promise.all([cfResponsePromise, vmResponsePromise]);

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 Wait for call-waiting before reading its state

CS-CALL-103 reads CALL_WAITING_BTN.innerText() immediately after loadSettings(), but this helper only waits for call-forwarding/voicemail responses and DND text before returning. If the call-waiting GET is slower than the DND request, the button can still say Fetching Call Waiting Status, causing an account with call waiting enabled to be treated as disabled and sending the test down the wrong branch/flaking; include the call-waiting response or final button text in the load barrier.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5f5ffbb22e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +833 to +837
.poll(
async () => calleePage.locator(CALLING_SELECTORS.INCOMING_ANSWER_BTN).isDisabled(),
{timeout: NO_INCOMING_CALL_TIMEOUT, intervals: [1000]}
)
.toBe(true);

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 Observe the full no-ring window

When call waiting is disabled, this expect.poll(...).toBe(true) succeeds on the first poll because the answer button starts disabled, so the test stops immediately instead of verifying that the second incoming call never appears during NO_INCOMING_CALL_TIMEOUT. If CF Busy regresses and the callee rings a few seconds later, this branch still passes; wait the full observation window (as the other no-ring tests do) before asserting the button remains disabled.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

validated If the pull request is validated for automation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants