← Glean Interview Insights

Glean·Software Engineer·Technical Phone Screen·Intermediate

Intermediate
Jun 2026

Summary

Interviewed at Glean for a Software Engineer role and got a Selenium coding question that looked straightforward until I started thinking through all the ways it could break on a JS-heavy page. More of a practical reliability exercise than a pure algorithms problem.

Questions Asked (5)

Q1

Write a Python function using Selenium WebDriver that extracts visible text from two specific elements on a JavaScript-rendered page. Explain your locator strategy, how you handle timing issues, and how you make the code resistant to flakiness.

Technical Trade-offsAPI & Integrations
Author's notes

My first instinct was to just call find_element and grab .text, which the interviewer immediately pushed back on.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the two elements and the page's JavaScript rendering behavior, then outline a robust locator strategy using stable attributes like data-testid or relative XPath. Explain how you'll use explicit waits with expected conditions to handle timing, and wrap interactions in retry logic or custom wait functions to mitigate flakiness. Finally, demonstrate the code with clear separation of concerns: driver setup, element location, text extraction, and error handling.

Pro tip: Mention that you avoid using absolute XPaths or brittle CSS selectors based on dynamic classes, and instead prefer semantic locators or custom data attributes that you can advocate adding to the application for testability. Also, note that you can use JavaScript execution to extract text if standard methods fail due to visibility issues, but only as a last resort.

1. Clarify requirements and environment

Ask clarifying questions about the two elements, the page's rendering framework (e.g., React, Angular), and any existing test infrastructure. Confirm that the elements are visible and contain text, and discuss potential dynamic loading.

2. Design locator strategy

Choose locators that are resilient to changes: prefer IDs, data-testid attributes, or relative XPaths with stable anchors. Avoid indexes and auto-generated classes. Explain how you would inspect the DOM and possibly collaborate with developers to add test IDs.

3. Implement explicit waits and synchronization

Use WebDriverWait with expected_conditions such as visibility_of_element_located or text_to_be_present_in_element. Set a reasonable timeout and polling interval. Discuss handling of AJAX or animations that might delay text appearance.

4. Write the function with error handling and retries

Structure the function to locate both elements, wait for them, extract text, and return a tuple or dict. Include try-except blocks for TimeoutException and NoSuchElementException, and consider a retry decorator for transient failures.

5. Discuss flakiness mitigation and trade-offs

Explain additional strategies like using a custom wait that checks for text stability, avoiding hard sleeps, and leveraging Selenium's built-in waits. Mention trade-offs between explicit waits and implicit waits, and the importance of logging for debugging.

Key Points to Mention

  • Use of explicit waits (WebDriverWait) over implicit waits or time.sleep to handle dynamic content.
  • Locator strategy: prioritize stable attributes (data-testid, id) and relative XPaths; avoid brittle selectors.
  • Handling of JavaScript-rendered content: ensure elements are attached and visible before extracting text.
  • Error handling: catch TimeoutException and NoSuchElementException, and implement retries for transient issues.
  • Flakiness reduction: avoid hard-coded sleeps, use polling with expected conditions, and consider custom wait conditions for text stability.
  • Code organization: separate driver setup, element location, and text extraction; include logging and clear return values.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

The element's text updates asynchronously after it first appears. How do you wait for the final value instead of catching an intermediate one?

Technical Trade-offsRoot Cause Analysis
Author's notes

Tricky follow-up.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the scenario and the risks of reading intermediate values, then explain a robust waiting strategy that targets the final value using condition-based waits or polling with a stable-state check. Emphasize avoiding fixed sleeps and instead using framework-provided mechanisms or custom polling that verifies the text has settled.

Pro tip: Mention that you always add a timeout and a clear failure message to your wait, and that you prefer waiting for the absence of changes over a fixed duration to avoid flakiness.

1. Clarify the scenario and risks

Restate the problem: the element appears with initial text, then updates asynchronously. Explain that reading too early yields intermediate values, causing flaky tests or incorrect logic.

2. Choose a waiting strategy

Select a condition-based wait (e.g., WebDriverWait with a custom expected condition) or a polling loop that checks for the final value. Avoid fixed sleeps.

3. Define the final-value condition

Specify what 'final' means: e.g., text equals an expected value, matches a pattern, or remains unchanged for a stability period. Use a stability check if the exact value is unknown.

4. Implement with timeout and error handling

Wrap the wait in a timeout and catch timeout exceptions to provide a clear failure message. Log the last observed value for debugging.

5. Validate and avoid flakiness

Test the wait under different network conditions and ensure it doesn't rely on timing. Consider using framework features like Selenium's expected conditions or Playwright's waitForFunction.

Key Points to Mention

  • Avoid fixed sleeps (e.g., Thread.sleep) because they are unreliable and slow.
  • Use condition-based waits (e.g., WebDriverWait, waitForFunction) that poll for a specific condition.
  • For unknown final values, wait for text to stabilize (no changes for a short period).
  • Set a reasonable timeout and handle timeout exceptions gracefully.
  • Leverage framework-specific utilities (Selenium, Playwright, Cypress) for waiting.
  • Consider the root cause: why does the text update asynchronously? Can the app provide a signal (e.g., data attribute) when final?

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

One of the elements is inside an iframe. What do you change in your approach?

Technical Trade-offsAPI & Integrations
Author's notes

Blanked for a second.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Acknowledge that iframes create isolated browsing contexts, so you must adjust your automation strategy to switch into the frame before interacting with elements. Explain that you would first identify the iframe, switch context, perform actions, and then switch back to the main document to avoid stale element references.

Pro tip: Mention that you should always wait for the iframe to be available and consider using a robust frame-switching utility that handles nested iframes and dynamic loading, as flaky tests often stem from improper frame handling.

1. Identify the iframe

Locate the iframe element using a unique selector (e.g., id, name, or index) and ensure it is fully loaded before interacting.

2. Switch context

Use the driver's switchTo().frame() method (or equivalent) to change the context to the iframe, making its elements accessible.

3. Interact with elements

Perform the required actions (click, send keys, etc.) on elements inside the iframe as you normally would.

4. Switch back

After completing actions, switch back to the default content (or parent frame) to continue interacting with the main page.

5. Handle edge cases

Account for nested iframes, dynamic iframes, and cross-origin restrictions by using appropriate waits and error handling.

Key Points to Mention

  • Iframes create separate browsing contexts, so standard element locators won't work without switching.
  • Use explicit waits to ensure the iframe and its contents are loaded before switching.
  • Always switch back to the default content after finishing inside the iframe to avoid NoSuchElementException.
  • For nested iframes, switch sequentially into each frame and then back out in reverse order.
  • Cross-origin iframes may require special handling or may be inaccessible due to same-origin policy.
  • Consider using a wrapper or utility function to encapsulate frame switching for better maintainability.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q4

How would you restructure this code into a Page Object pattern so locators aren't duplicated across tests?

System DesignTechnical Trade-offs
Author's notes

Talked through keeping selectors as class-level constants and wrapping the wait logic in methods.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by acknowledging the problem of duplicated locators and their maintenance cost, then propose a Page Object pattern that encapsulates locators and page-specific actions. Walk through a concrete refactoring example, highlighting how tests become more readable and resilient, and discuss trade-offs like abstraction overhead and when to use component objects.

Pro tip: Emphasize that Page Objects should expose user-centric methods (e.g., login()) rather than raw locators, and mention using a base page class for shared utilities to avoid duplication across page objects themselves.

1. Identify duplication and pain points

Point out where locators are repeated across tests and the resulting maintenance burden, such as updating multiple files when the UI changes.

2. Design page objects

Create a class for each page or component, with locators as private fields and public methods that represent user actions or queries.

3. Refactor tests to use page objects

Replace direct locator usage in tests with calls to page object methods, ensuring tests focus on behavior rather than implementation details.

4. Address shared components and inheritance

Extract common elements (e.g., navigation bar) into base classes or component objects to further reduce duplication and promote reuse.

5. Discuss trade-offs and best practices

Talk about when Page Objects might be overkill, how to keep them maintainable, and the importance of not exposing locators publicly.

Key Points to Mention

  • Single source of truth for locators
  • Encapsulation of page structure and behavior
  • Improved test readability and maintainability
  • Use of base page classes for shared functionality
  • Avoiding leaky abstractions (don't expose locators)
  • Trade-offs: abstraction overhead vs. duplication reduction

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q5

The selector is correct but the test still fails roughly once every fifty runs. How do you diagnose and fix that?

Root Cause AnalysisTechnical Trade-offs
Author's notes

This is the kind of question where you either have war stories or you don't.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by acknowledging that a correct selector failing intermittently points to a race condition or timing issue, not a locator problem. Then outline a systematic debugging process: reproduce with logging, isolate the flaky step, and apply a robust fix like explicit waits or retry logic. Finally, discuss how to prevent recurrence through monitoring and test design improvements.

Pro tip: Don't just add a sleep—that's a band-aid. Instead, identify the specific asynchronous operation and wait for its completion signal, such as a network response or DOM state change.

1. Reproduce and Gather Data

Run the test in a loop with verbose logging and screenshots on failure to capture the exact state when it breaks. Check if the failure correlates with timing, parallel execution, or environment.

2. Isolate the Flaky Step

Narrow down which action or assertion is failing by adding checkpoints or using test runners that report step-level timing. Determine if the selector is evaluated before the element is ready.

3. Identify the Root Cause

Look for asynchronous operations (AJAX, animations, lazy loading) that might delay element availability or cause it to be replaced. Consider if the element is detached and reattached, making the selector stale.

4. Apply a Robust Fix

Replace implicit waits with explicit waits for a specific condition (e.g., element visible, enabled, or stable). If the element is dynamic, use a more resilient selector or wait for a stable state.

5. Verify and Prevent

Run the test many times to confirm the fix. Add monitoring to detect future flakiness and consider refactoring the test to avoid timing dependencies altogether.

Key Points to Mention

  • Race conditions and timing issues are common causes of flaky tests, even with correct selectors.
  • Use explicit waits (e.g., WebDriverWait) instead of implicit waits or hard sleeps.
  • Check for element staleness or detachment due to DOM updates.
  • Consider network latency, animations, or third-party scripts affecting element readiness.
  • Implement retry logic only as a last resort, and ensure it doesn't mask real bugs.
  • Improve test reliability by using stable selectors (e.g., data-testid) and waiting for application-specific signals.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.