service-teams-browser-bot/CHANGES_SINCE_WORKING.md
2026-05-12 15:19:41 +02:00

7.2 KiB

Changes since last working state ("jetzt geht es" — 12 May 2026, 14:01)

All changes are uncommitted (working tree vs HEAD). HEAD = last git commit (the known-good baseline from ~3 weeks ago).

Legend

  • PRE-SUCCESS: Change was present at 14:01 when the bot successfully joined
  • POST-SUCCESS: Change was made after 14:01 (potential regression source)
  • REVERTED: Was added after 14:01 then reverted — should be back to pre-success state

1. audioCaptureProcedure.ts — Audio Capture Gating (PRE-SUCCESS)

What: Complete rewrite of the RTCPeerConnection wrapper. Instead of immediately building an AudioContext/MediaStreamSource on every track event, the wrapper now:

  • Sets window.__audioCaptureEnabled = false by default
  • Only logs diagnostics while disabled (no clone, no AudioContext, no MediaStream)
  • Exposes window.__audioCaptureAttachTrack(pc, track) as the audio graph builder
  • startCapture() (called AFTER in_meeting) sets the flag to true and retroactively attaches existing tracks via getReceivers()
  • The ended handler does passive cleanup (no ctx.close(), no disconnect())

Why: Prevents rejectMediaDescriptionsUpdateAsync crash by keeping out of Teams' WebRTC pipeline during pre-join/lobby/SDP renegotiation.

Risk: This was the exact fix that led to "jetzt geht es". Should be safe.


2. joinProcedure.ts — Blind Wait Elimination + Selector Rewrite (PRE-SUCCESS)

2a. New helper functions (replacing waitForTimeout)

  • _waitForPreJoinAfterLauncher() — waits for pre-join UI (10s timeout)
  • _waitForNoAudioVideoModalGone() — waits for no-AV modal dismissal
  • _waitForPermissionOverlayCleared() — waits for permission dialog gone
  • _waitForLeaveUiSettled() — waits for hangup button to disappear

All waitForTimeout calls replaced with these. Timeout is 10s (vs original 1-2s).

2b. isInMeetingLobby() rewrite

OLD (HEAD): Text-based detection using bodyText.includes('will let you in') + data-tid fallback. NEW: Purely structural selectors: [data-tid="lobby-screen"], [data-cid="lobby-screen"], [id*="lobby"], [class*="lobby" i], etc.

2c. isInMeeting() rewrite

OLD (HEAD): Mixed text-based (aria-label*="Leave", bodyText.includes('Mute')) + data-tid selectors. NEW: Purely structural: button[id="hangup-button"], button[id="microphone-button"], [data-cid="ts-hangup-btn"], [data-cid="calling-unified-bar"], etc. Fallback uses DOM structure check (class-based calling-controls, button ID counting).

Risk: The new _waitForPreJoinAfterLauncher() has a 10s timeout. In logs, this timeout fires ("Pre-join UI not detected after launcher") — the old 2s waitForTimeout was faster. This extra delay might change timing.


3. orchestrator.ts — Lobby Admission + Browser Args (MIXED)

3a. _waitForMeetingAdmission() (POST-SUCCESS, then re-fixed)

At 14:01: Had wasInLobby tracking — when lobby disappeared, it kept waiting patiently for meeting UI. After 14:01: Was simplified to just poll isInMeeting() without tracking lobby state. Bot couldn't detect admission. Current: Re-added wasInLobby tracking + isInMeetingLobby() check per iteration.

3b. _launchBrowser() comment (PRE-SUCCESS)

Added documentation comment explaining why anon and auth use different Chromium args.

3c. _attemptAuthJoin() cleanup (PRE-SUCCESS)

Minor comment/formatting changes in the anon=true stripping logic.

3d. _stripAnonFromInnerMeetingUrl() comment (PRE-SUCCESS)

Expanded docstring.

3e. ChatProcedure constructor trailing comma (PRE-SUCCESS)

Cosmetic: added trailing comma after the callback parameter.


4. chatProcedure.ts — Simplified Compose + Root-Cause Guard (MIXED)

4a. _ensureComposeExpanded() (PRE-SUCCESS — was being developed at 14:01)

New method that detects Teams' "simplified compose" layout (light-meetings) and clicks the expand button so ckeditor is visible.

4b. Updated _isChatPanelOpen() selectors (PRE-SUCCESS)

Added [data-tid="ckeditor"], [data-tid="newMessageCommands-expand-compose"], [data-tid="simplified-compose-bottom-toolbar"].

4c. Root-cause guard: if (!text && author !== 'Unknown') (PRE-SUCCESS)

In both periodic scan and MutationObserver paths: the innerText fallback only fires when an author was actually identified. Prevents "Unknown: 22:04" timestamp noise.

4d. Container fallback for light-meetings (PRE-SUCCESS)

When the chat container has offsetHeight === 0 or yields 0 candidates but global fui-ChatMessage elements exist, promotes search target from container to document.

4e. _sendChatMessage() selector additions (PRE-SUCCESS)

Added [data-tid="ckeditor"] as a selector for the input box.

4f. Reverted changes (were POST-SUCCESS, now back to PRE-SUCCESS state)

  • botName constructor parameter → removed
  • expanded noisePatterns → removed
  • isOwnAuthor() skip logic → removed

5. teamsActionsService.ts — Blind Wait Elimination (PRE-SUCCESS)

Replaced waitForTimeout calls with targeted waits:

  • Menu dismissal: waitForFunction(() => !document.querySelector('[role="menu"]'))
  • Chat input focus: waitForFunction(() => document.activeElement?.matches(...))
  • More menu: waitForSelector('[role="menu"]')
  • Captions button: waitForSelector('#closed-captions-button')
  • Chat panel input: waitForSelector('[data-tid="ckeditor-replyConversation"]')
  • Removed delay after media toggles

6. authProcedure.ts — Blind Wait Elimination (PRE-SUCCESS)

Replaced waitForTimeout calls with targeted waits:

  • After sign-in click: wait for MFA/error/KMSI indicator
  • After email Next click: wait for password input
  • After "Stay signed in": wait for KMSI banner dismissal

7. authTestProcedure.ts — Blind Wait Elimination (PRE-SUCCESS)

Removed redundant waitForTimeout calls and replaced with targeted waitForSelector calls for:

  • Login page elements, pre-join screen, meeting UI, launcher, sign-in dialog

8. backgroundProcedure.ts — Blind Wait Elimination (PRE-SUCCESS)

Replaced waitForTimeout calls with targeted waits:

  • Background effects panel visibility
  • File input appearance after add-image click
  • Background thumbnail appearance after upload
  • Panel dismissal via Escape

Summary: What to roll back for a clean test

If rolling back to HEAD (git checkout):

  • You lose the audio capture gating (the fix that made "jetzt geht es" work)
  • You lose the blind wait elimination (improves robustness)
  • You lose the chat simplified compose fix
  • You lose the structural selector rewrites for lobby/meeting detection

Recommended selective rollback (keep what was working):

  1. Keep audioCaptureProcedure.ts changes (audio capture gating)
  2. Keep chatProcedure.ts changes (compose expand, root-cause guard, container fallback)
  3. Consider reverting joinProcedure.ts helper timeouts back to shorter values (10s → 2-3s) — the 10s _waitForPreJoinAfterLauncher is timing out and adding unnecessary delay
  4. Keep orchestrator.ts _waitForMeetingAdmission with wasInLobby tracking
  5. The blind-wait changes in auth/background/teamsActions are safe (only affect those specific flows)