top of page
90s theme grid background
Writer's pictureGunashree RS

Blink Element in Testing: Causes, Solutions & Strategies

Introduction: The Issue of Blink Elements in Software Testing

In software testing, encountering "blink elements" can be a common but frustrating problem. Picture this: you’re running an automated test to check the presence of a loading spinner on a webpage. The spinner appears and disappears so quickly that the test often fails to capture its presence, leading to inconsistent test outcomes. This phenomenon, often termed a "blink element," occurs when an element is briefly visible but disappears so rapidly that it goes unnoticed by the test runner.


Such blink elements result in flaky tests, where test outcomes vary between runs without any changes to the code. This not only affects the reliability of your test suite but also slows down the development pipeline. In this article, we will explore the underlying causes of blink elements, demonstrate their effects in real-world testing scenarios, and provide actionable solutions to handle them effectively.


Understanding the Blink Element: When and Why Does It Occur?

A blink element in testing refers to an element that appears momentarily on the webpage before disappearing too quickly for the test runner to detect it consistently. For example, loading spinners or progress bars that flash briefly while data is fetched from a server are typical instances of blink elements.


Blink element

1. Common Causes of Blink Elements in Testing

To tackle blink elements effectively, it’s important to identify why they occur. Here are some common causes:

  • Fast Loading: If data fetching from the server happens almost instantly, loading elements like spinners may appear and disappear too quickly for the test to detect.

  • Race Conditions: Asynchronous operations such as network requests and UI rendering can result in race conditions, where the test runner executes assertions before the element’s state has changed.

  • Timing Sensitivity: Test runners typically have a polling interval to check for assertions. If an element blinks in and out between these intervals, it can go unnoticed.

  • Negative Assertions: Relying on assertions like .should('not.be.visible') can lead to false negatives if the test misses the brief appearance of the element.

  • Network Variability: Variations in network speed during API calls can lead to inconsistent loading times, making the blink element more unpredictable.

By understanding these causes, we can now explore how to design robust tests that handle blink elements effectively.


2. Identifying Blink Elements: Recognizing and Testing the Issue

The first step to solving the problem of blink elements is recognizing when and where they occur. A common scenario is during the initial data loading of an application, where a loading spinner is expected to appear briefly. Let’s look at an example test designed to observe the loading element.


Example: Testing a Blink Element in a Web Application

javascript

describe('TodoMVC App', () => {
  it('shows loading element', () => {
    cy.visit('/?delay=500');
    cy.get('.loading').should('be.visible');
    cy.get('.loading').should('not.be.visible');
    cy.get('li.todo').should('have.length', 2);
  });
});

In this test, the loading element is expected to appear when the page is visited and disappear once the data has loaded. However, if the loading happens too fast, the test may "blink" and miss the element. This is a classic example of a blink element scenario leading to a flaky test.


Running the Test Multiple Times

To identify blink elements, try running the test multiple times using a loop to observe its behavior across different executions.

javascript

describe('TodoMVC App', () => {
  Cypress._.times(20, (k) => {
    it(`shows loading element ${k}`, () => {
      cy.visit('/?delay=500');
      cy.get('.loading', { timeout: 800 }).should('be.visible');
      cy.get('.loading').should('not.be.visible');
      cy.get('li.todo').should('have.length', 2);
    });
  });
});

Running this test 20 times may reveal that the loading element test fails intermittently, highlighting the blink element problem. For instance, you might see a failure rate of around 1/3 if the element appears and disappears too rapidly.


3. Root Cause: How Blink Elements Slip Through the Cracks

If we dig deeper into the root cause of blink elements, we realize that it often comes down to timing. Tests typically have a default polling interval (e.g., 20-30 milliseconds) when checking for element visibility. If an element blinks in and out within this interval, the test runner may miss it, resulting in failed assertions.


Timing the Blink

To investigate further, let’s measure the duration it takes for the loading element to appear and disappear.

javascript

loadTodos({ commit, state }) {
  console.log('loadTodos start, delay is %d', state.delay);
  setTimeout(() => {
    commit('SET_LOADING', true);
    const loadingStarted = Number(new Date());

    axios.get('/todos')
      .then(r => r.data)
      .then(todos => {
        commit('SET_TODOS', todos);
        commit('SET_LOADING', false);
        const loadingStopped = Number(new Date());
        const loadingTook = loadingStopped - loadingStarted;
        console.log('>>>loading took', loadingTook);
      })
      .catch(e => {
        console.error('could not load todos');
      });
  }, state.delay);
},

By printing the elapsed time to the console, we can determine if the loading speed is causing the blink element. In cases where the loading time is extremely short (e.g., 15-16 milliseconds), the test is more likely to fail.


4. Strategies for Handling Blink Elements in Tests

To reliably handle blink elements, we must adapt our testing strategies. Here’s how you can effectively deal with blink elements in your tests:

Adjusting Timeout Settings

One way to manage blink elements is by adjusting the timeout for specific assertions. If you expect an element to appear within a short time frame, set a smaller timeout to avoid unnecessary delays.

javascript

cy.get('.loading', { timeout: 800 }).should('be.visible');

However, if the blink is too fast for even a shorter timeout, this method alone won’t solve the problem.


Implementing cy.intercept for Delaying Network Responses

A more robust approach is to use cy.intercept to control network responses, introducing a deliberate delay that allows the blink element to appear long enough for the test to capture it.

javascript

it(`shows loading element ${k}`, () => {
  cy.intercept('/todos', {
    fixture: 'todos.json',
    delayMs: 1000,
  });
  cy.visit('/?delay=500');
  cy.get('.loading', { timeout: 800 }).should('be.visible');
  cy.get('.loading').should('not.be.visible');
  cy.get('li.todo').should('have.length', 2);
});

This method ensures that the loading element remains visible for a sufficient duration, making the test more reliable.


Using Custom Assertions for Better Control

Instead of relying on standard assertions like .should('be.visible'), create custom assertions to handle the timing of blink elements more effectively. By introducing a delay within the assertion callback, you provide extra time for the element to stabilize.

javascript

let previous = Number(new Date());
cy.get('.loading', { timeout: 800 }).should(($el) => {
  const current = Number(new Date());
  const elapsed = current - previous;
  console.log('>>>should', elapsed);
  previous = current;
  expect($el).to.be.visible;
});

This technique gives you better insight into the element's visibility duration and helps identify cases where the element blinks too quickly.


Implementing Test Retries for Flaky Tests

For tests with intermittent failures due to blink elements, enabling test retries is a quick workaround. Cypress, for instance, provides built-in support for test retries. While retries don't fix the underlying issue, they reduce the impact of flakiness on the test suite.


Ensuring Proper Element Timing in Your Code

If your application is responsible for the blink elements, consider modifying the implementation to introduce a minimum display time for elements like loading spinners. A delay of even 50 milliseconds can be enough to make the element detectable by test runners without impacting user experience.


5. Fixing the Blink Element Issue: Putting It All Together

In most cases, a combination of the above strategies provides the best solution to handle blink elements. For example, in our test scenario:

  • Introduce a network delay using cy.intercept to control the loading duration.

  • Adjust timeouts to avoid false negatives.

  • Use custom assertions to provide greater control over the element's visibility checks.

By carefully designing your tests and incorporating these techniques, you can minimize the impact of blink elements and build a more reliable test suite.


Conclusion: A Steady Approach to Handling Blink Elements

Dealing with blink elements in testing can be a challenging task, especially when they lead to flaky tests that compromise the reliability of your testing process. Understanding the root causes of blink elements, such as fast loading and race conditions, is crucial in addressing them effectively. By employing strategies like custom assertions, network request interception, timeout adjustments, and test retries, you can significantly reduce the impact of blink elements on your test suite.

The key takeaway is to adapt your testing strategy to the unique characteristics of blink elements in your application. By implementing the right solutions, you can ensure that your tests capture elements consistently, leading to a more robust and trustworthy testing process.


Key Takeaways

  • Blink elements occur due to fast loading, race conditions, and timing sensitivity in tests.

  • Running tests multiple times can help identify the presence of blink elements.

  • Adjusting timeout settings and using cy.intercept can control the visibility of blink elements.

  • Custom assertions provide greater control over element visibility checks, improving test reliability.

  • Test retries can mitigate the impact of blink elements but should not be the sole solution.

  • Modifying the application to introduce a minimum display time for elements can enhance detectability.




FAQs About Blink Elements in Testing


Q1: What is a blink element in software testing?

A: A blink element is an element on a webpage that appears and disappears so quickly that it is missed by the test runner, resulting in inconsistent test outcomes.


Q2: How do blink elements cause flaky tests?

A: Blink elements can cause flaky tests by appearing and disappearing too fast for the test runner to detect, leading to false negatives and varying results across test runs.


Q3: Can adjusting timeouts fix blink element issues?

A: Adjusting timeouts can help manage blink elements by reducing the delay before an assertion fails. However, it may not be sufficient if the blink occurs faster than the polling interval of the test runner.


Q4: How does cy.intercept help with blink elements?

A: cy.intercept allows you to control network responses and introduce delays, ensuring that elements like loading spinners remain visible long enough for the test to detect them reliably.


Q5: Why do race conditions lead to blink elements?

A: Race conditions occur when asynchronous operations like network requests and UI rendering are not synchronized. This can cause elements to appear and disappear unpredictably, creating blink elements.


Q6: Should I rely solely on test retries to handle blink elements?

A: No, test retries should be used as a fallback mechanism. The primary focus should be on identifying and addressing the root cause of blink elements to ensure test reliability.


Q7: How can custom assertions improve blink element detection?

A: Custom assertions allow you to introduce delays within the assertion process, providing greater control over how long the test runner waits for the element to become visible.


Q8: Can blink elements affect video recordings of test runs?

A: Yes, since videos usually record at 30 frames per second (with frames spaced 33 milliseconds apart), elements that blink faster than this interval may not be captured in the video.


Article Sources


Comments


bottom of page