Blocking Google Analytics in Playwright Tests
Tags: webdev, playwright, testing
Published: 2023-06-14 14:43:31

## Testing in a Production Environment

There are instances where it becomes necessary to test in a production environment where Google Analytics is enabled. This requirement might surface for a variety of reasons. You could be looking to verify features that only come into play in a production scenario. You might want to gauge the real-world performance of your application. Or perhaps, you are troubleshooting certain issues that only manifest under production conditions.

In such scenarios, you're interacting with the same system setup that your end-users do. This allows you to get a more accurate understanding of the user experience, placing you in a better position to identify and resolve issues.

## The Problem with sending data to Google Analytics

However, while testing in a production environment, it's critical that your tests do not feed data to Google Analytics. The reason is simple but important - test data can distort your analytics. This can lead to misunderstandings and consequently, incorrect decisions.

Test data might artificially boost page views or inflate bounce rates. It could create conversion paths that aren't really there. Essentially, your understanding of user behavior could end up being warped due to the interference of test data.

This is why it's so important to ensure your tests do not interfere with your Google Analytics data. The focus should always be on maintaining the accuracy and reliability of your user data.

We'll dig into several techniques to block Google Analytics in your Playwright tests, including:

1. Blocking the collect endpoint
2. Injecting a script
3. Debug mode

Let's dive in!

## 3 Ways to Block Google Analytics in Playwright Tests

### Block the Collect Endpoint

Preventing Google Analytics from creeping into your Playwright tests can be as simple as intercepting the requests to the `/g/collect` endpoint. Google Analytics uses this endpoint to transmit data. You just need to intercept the request and respond with a 204 No Content status. This imitates the usual response from Google Analytics.

Look at this TypeScript code example illustrating this method:

```typescript
await page.route('https://www.google-analytics.com/g/collect*', (route) => {
  route.fulfill({
    status: 204,
    body: '',
  });
});
```

I like this approach because it does not actually block the request. It just responds with a 204 No Content status, which is the same response that Google Analytics would send. This means that Google Analytics SDK thinks that the request was successful, and everything continues to work as expected.

You can verify that this method works by checking the Google Analytics Realtime – there should be no active users when running your tests.

### Inject a Script

An alternate path to block Google Analytics is by injecting a script that communicates to Google Analytics that the user has opted out. The script suggested by [Google Analytics](https://developers.google.com/tag-platform/devguides/privacy#turn%5Foff%5Fgoogle%5Fanalytics) goes like this:

```html
<script>
window['ga-disable-GA_MEASUREMENT_ID'] = true;
</script>
```

> Note: Replace `GA_MEASUREMENT_ID` with your Google Analytics measurement ID, e.g. `window['ga-disable-G-2J3Z7ZMQRX'] = true;`

To embed this script using Playwright, use the `page.addInitScript` method:

```typescript
await page.addInitScript({
  content: `window['ga-disable-GA_MEASUREMENT_ID'] = true;`,
});
```

The reason I dislike this approach is because it requires you to know the Google Analytics measurement ID. This is not a problem if you're testing a single website, but if you're testing multiple websites, you'll need to know the measurement ID for each one. This can be a pain to manage.

### Embrace Debug Mode in Google Analytics

Sometimes, the road to better testing might mean making some modifications to the application, as in the case of utilizing the [`debug_mode`](https://support.google.com/analytics/answer/7201382) in Google Analytics. This mode can be a lifesaver when it comes to distinguishing your device in the [DebugView](https://support.google.com/analytics/answer/7201382?hl=en) under Debug Device. However, the limitation of this approach is that it requires you to alter the application.

The `debug_mode` parameter needs to be added during the `gtag` initialization, which means it can't be passed directly through URL parameters, cookies, or headers. If you have access to the application, you might need to hunt for the localStorage variable `ga_debug_mode` and set the debug flag when it is identified.

```ts
gtag('config', 'G-XXXXXX', { debug_mode: window.localStorage.getItem('ga_debug_mode') === 'true' });
```

In your Playwright tests, you can use the `storageState` feature to single out the requests that should use the debug mode.

Here is a `playwright.config.ts` example of how you can do that:

```ts
import type { PlaywrightTestConfig } from '@playwright/test';

const storageState = {
  cookies: [],
  origins: [{
    origin: 'https://ray.run',
    localStorage: [{ name: 'ga_debug_mode', value: 'true' }]
  }]
};

const config: PlaywrightTestConfig = {
  use: {
    storageState,
    // ...
  },
};
```

By setting the `ga_debug_mode` in localStorage to `true`, you enable the debug mode for your Playwright tests. This helps you isolate the test requests in the DebugView of Google Analytics, and keep your test data from affecting your Google Analytics insights.

## Ineffective Methods

### Spoofing User-Agent

A popular proposition for blocking Google Analytics is to spoof the user-agent. I've seen this in countless of Stack Overflow questions. The theory suggests that if you present the user-agent as a recognizable bot to Google Analytics, it won't transmit data. However, after trying out several user-agent strings, like "bot", "googlebot", and the certified [Googlebot user-agent](https://developers.google.com/search/docs/crawling-indexing/overview-google-crawlers), this method turned out to be unfruitful.

```markdown
Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/W.X.Y.Z Safari/537.36
```

The analytics data still reflected the requests to Google Analytics, regardless of the user-agent string.

## Wrapping Up

It's paramount to prevent your Playwright tests from meddling with your Google Analytics data. You can either block the necessary requests or embed a script that opts out of data collection. The preferred way is to block the `/g/collect` endpoint as it's both simple and efficient. You can also consider script injection, though it might not work with some tag managers. If you have access to the application, you can enable the debug mode in Google Analytics. This will help you isolate the test requests in the DebugView of Google Analytics, and keep your test data from affecting your Google Analytics insights.