From c91cf3739dbfed5b9601517324f4ef28c4118459 Mon Sep 17 00:00:00 2001 From: AshGDS <8880610+AshGDS@users.noreply.github.com> Date: Wed, 22 Nov 2023 11:43:36 +0000 Subject: [PATCH 1/4] Simplify chrome/chromedriver documentation Also adds VPN notice to the homepage --- README.md | 19 ++++++++++--------- app/views/home/index.html.erb | 4 +++- data/interactions.yml | 6 +++--- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 7c50e5d..ddebe59 100644 --- a/README.md +++ b/README.md @@ -24,21 +24,22 @@ bundle exec npm install bundle exec yarn install ``` +## Setup Chrome for Testing + chromedriver -## Ensure your chromedriver is installed/up to date/has executable permission -- Update to the latest version of Google Chrome. -- Note your version of Google Chrome by clicking the Menu in the top right of Chrome, then clicking Help > About Chrome -- Download the version of `chromedriver` relevant to your version of Google Chrome from https://googlechromelabs.github.io/chrome-for-testing/ - you'll want the `mac-arm64` version if you're on an M1 Mac. **Make sure you have downloaded `chromedriver` and not `chrome` ! (see screenshot)** -![chromedriver](https://github.com/AshGDS/analytics-robot/assets/8880610/ab28421b-9ad1-499d-aefd-146b742bfc96) - -- Copy the relevant chromedriver URL from the table, and open it in a new tab so that the download process begins. -- Once download, extract the `.zip` file by double clicking it. -- Move the `chromedriver` file to `/usr/local/bin`. You can do this by doing `cp /Users/[YOUR.NAME]/Downloads/chrome-mac-arm64/chromedriver /usr/local/bin/chromedriver` +- Download both `chrome` AND `chromedriver` from https://googlechromelabs.github.io/chrome-for-testing/ - you'll want the `mac-arm64` version if you're on an M1 Mac. +- Extract the zip file for `chrome` by double clicking the downloaded file. +- Open your terminal, and go to the folder where Chrome was extracted, e.g. `~/Downloads/chrome-mac-arm64` +- Run `sudo xattr -cr 'Google Chrome for Testing.app'`. This removes Apple's security, which prevents files that originated from zip files from being executed. +- In your Finder, move `Google Chrome for Testing.app` into your Mac's Applications folder, like you usually do to install applications on a Mac. +- Now, we need to setup `chromedriver`. +- Extract the `.zip` file for `chromedriver` by double clicking the downloaded file. +- Move the `chromedriver` file to `/usr/local/bin`. You can do this by running `cp /Users/[YOUR.NAME]/Downloads/chrome-mac-arm64/chromedriver /usr/local/bin/chromedriver` - Change directory to `/usr/local/bin` in your terminal - Run `chmod +x chromedriver` to make chromedriver executable - Run `sudo xattr -r -d com.apple.quarantine chromedriver` to remove Apple's security quarantine from the file - Restart your terminal, and to test chromedriver is working, run `chromedriver -v` +- You shouldn't need to run these steps ever again, unless you want to update your test version of Google Chrome ### Running the application diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb index dffadc8..4db55bb 100644 --- a/app/views/home/index.html.erb +++ b/app/views/home/index.html.erb @@ -4,7 +4,9 @@

Analytics Robot

Run our automated GA4 tests on an environment

-

This form will run any tests listed in interactions.yaml on the chosen environment

+

This form will run any tests listed in interactions.yaml on the chosen environment.

+

Connect to the developer VPN to test on staging/integration environments.

+ <%= form_with url: fake_path, method: :post do |form| %>
<%= form.label :environment, class: "govuk-label" %> diff --git a/data/interactions.yml b/data/interactions.yml index 158e72e..a26ee6f 100644 --- a/data/interactions.yml +++ b/data/interactions.yml @@ -1,7 +1,7 @@ accordions: class: - - govuk-accordion__show-all - - govuk-accordion__section-heading + - '.govuk-accordion__show-all' + - '.govuk-accordion__section-heading' urls: - https://www.[ENVIRONMENT]/coronavirus # - https://www.[ENVIRONMENT]/hmrc-internal-manuals/employment-income-manual/updates @@ -19,7 +19,7 @@ accordions: # - https://www.[ENVIRONMENT]/guidance/mot-inspection-manual-for-private-passenger-and-light-commercial-vehicles/5-axles-wheels-tyres-and-suspension tabs: class: - - govuk-tabs__tab + - '.govuk-tabs__tab' urls: - https://www.[ENVIRONMENT]/renew-driving-licence - https://www.[ENVIRONMENT]/bank-holidays From 30d1bfbf3872bd9920ce1bfeabf83f12b155a34f Mon Sep 17 00:00:00 2001 From: AshGDS <8880610+AshGDS@users.noreply.github.com> Date: Wed, 22 Nov 2023 13:48:23 +0000 Subject: [PATCH 2/4] Add link click checking, improve the 'See all events on a page' code Uses JavaScript for click events instead as selenium does not interact with hidden elements but JavaScript does. --- app/controllers/developer_controller.rb | 53 ++++++++++++++------ app/controllers/home_controller.rb | 2 +- app/javascript/channels/developer_channel.js | 19 ++++++- app/javascript/channels/faker_channel.js | 2 +- app/models/fake_events.rb | 9 ++++ app/models/gtm_event_generator.rb | 2 +- app/views/developer/index.html.erb | 1 + data/interactions.yml | 7 ++- 8 files changed, 75 insertions(+), 20 deletions(-) diff --git a/app/controllers/developer_controller.rb b/app/controllers/developer_controller.rb index b192dd8..82e6481 100644 --- a/app/controllers/developer_controller.rb +++ b/app/controllers/developer_controller.rb @@ -27,20 +27,43 @@ def accept_cookies(driver) end def click_elements(driver) - elements = driver.find_elements(:xpath, "//*[@data-ga4]") - elements.each do |element| - data_ga4 = JSON.parse(element.attribute("data-ga4")) - begin - if data_ga4["type"] == "accordion" - %w[opened closed].each do |_state| - element.click - end - else - element.click - end - rescue StandardError - Rails.logger.debug "Element [#{element.tag_name} - #{element.accessible_name}] is not interactable!" - end - end + + header_search_button = driver.find_element(:css, "#super-search-menu-toggle") + header_search_button.click unless header_search_button.nil? + + # We use JavaScript to fake the clicks, because Selenium errors when you try to interact with hidden elements. + driver.execute_script(' + document.addEventListener("click", function(e) { + e.preventDefault(); + })') + driver.execute_script(' + document.addEventListener("submit", function(e) { + e.preventDefault() + })') + + driver.execute_script('window.ga4Links = document.querySelectorAll("[data-ga4-link]")') + driver.execute_script('window.ga4Events = document.querySelectorAll("[data-ga4-event]")') + driver.execute_script('window.ga4FormSubmits = document.querySelectorAll("[data-ga4-form] [type=submit]")') + + driver.execute_script( + 'for (var i = 0; i < window.ga4Links.length; i++) { + window.GOVUK.triggerEvent(window.ga4Links[i], "click") + }') + + driver.execute_script( + 'for (var i = 0; i < window.ga4Events.length; i++) { + window.GOVUK.triggerEvent(window.ga4Events[i], "click") + + // If the element is expandable, like an accordion, click it twice so that it gives us both the open and closed state. + if(window.ga4Events[i].closest("[data-ga4-expandable]")) { + window.GOVUK.triggerEvent(window.ga4Events[i], "click") + } + }') + + driver.execute_script( + 'for (var i = 0; i < window.ga4FormSubmits.length; i++) { + window.GOVUK.triggerEvent(window.ga4FormSubmits[i], "click") + }') + end end diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index 0c4a565..128e60f 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -1,7 +1,7 @@ class HomeController < ApplicationController def index @interaction_types = ApplicationController.helpers.interaction_types - @environments = %w[gov.uk staging.publishing.service.gov.uk integration.publishing.service.gov.uk] + @environments = %w[integration.publishing.service.gov.uk staging.publishing.service.gov.uk gov.uk] end def fake diff --git a/app/javascript/channels/developer_channel.js b/app/javascript/channels/developer_channel.js index 57dd660..f76e986 100644 --- a/app/javascript/channels/developer_channel.js +++ b/app/javascript/channels/developer_channel.js @@ -10,6 +10,7 @@ consumer.subscriptions.create('DeveloperChannel', { }, received (data) { + console.log(data) // Output the dataLayer JSONs to the console for developer benefit const url = document.getElementById('url').value const outputElement = document.getElementById('developer-output') @@ -81,7 +82,23 @@ consumer.subscriptions.create('DeveloperChannel', { const pre = document.createElement('pre') const code = document.createElement('code') - code.innerHTML = this.prettyPrint(JSON.parse(body)) + const dataLayerEvents = JSON.parse(body) + for(var i = 0; i < dataLayerEvents.length; i++) { + + var dataLayerEvent = dataLayerEvents[i] + var summary = 'Event' + if(dataLayerEvent.event_data) { + summary = dataLayerEvent.event_data.event_name + ' - ' + dataLayerEvent.event_data.type + ' - ' + dataLayerEvent.event_data.text + } + else if (dataLayerEvent.page_view) { + summary = 'Pageview' + } + else if (dataLayerEvent.search_results) { + summary = 'Search Results' + } + + code.innerHTML += '
' + summary + '' + this.prettyPrint(dataLayerEvents[i]) + '
' + } pre.append(code) div.append(pre) diff --git a/app/javascript/channels/faker_channel.js b/app/javascript/channels/faker_channel.js index c6daa45..806bae5 100644 --- a/app/javascript/channels/faker_channel.js +++ b/app/javascript/channels/faker_channel.js @@ -11,7 +11,7 @@ consumer.subscriptions.create('FakerChannel', { received (data) { const json = JSON.parse(data) - + console.log(json) // Output the dataLayer JSONs to the console for developer benefit let dataDisplay = 'Event:
' dataDisplay += '' dataDisplay += '' diff --git a/app/models/fake_events.rb b/app/models/fake_events.rb index 069c83f..d0c61a7 100644 --- a/app/models/fake_events.rb +++ b/app/models/fake_events.rb @@ -33,6 +33,15 @@ def fake_events clickable.click output_event_data end + elsif interaction_type == "main_content_links" + driver.execute_script(' + document.addEventListener("click", function(e) { + if(!e.target.hasAttribute("data-ga4-expandable")) { + e.preventDefault(); + } + })') + clickable.click + output_event_data else clickable.click output_event_data diff --git a/app/models/gtm_event_generator.rb b/app/models/gtm_event_generator.rb index d2a202b..e9356eb 100644 --- a/app/models/gtm_event_generator.rb +++ b/app/models/gtm_event_generator.rb @@ -30,7 +30,7 @@ def iterations def clickables elements = [] find_interaction_class.each do |klass| - elements += driver.find_elements(class: klass) + elements += driver.find_elements(css: klass) end elements end diff --git a/app/views/developer/index.html.erb b/app/views/developer/index.html.erb index 6017cdc..6776666 100644 --- a/app/views/developer/index.html.erb +++ b/app/views/developer/index.html.erb @@ -4,6 +4,7 @@

See all GA4 events for a given page

This page shows all the possible GA4 events for a given URL. This is a work in progress - only a few interactions are implemented.

+

Currently, this works by loading a page, and clicking every element with data-ga4-event, data-ga4-link, or data-ga4-form (with some JS to prevent default behaviour.)

<%= form_with url: runner_path, method: :post do |form| %>

<%= form.label :url, class: "govuk-label" %> diff --git a/data/interactions.yml b/data/interactions.yml index a26ee6f..eb9e897 100644 --- a/data/interactions.yml +++ b/data/interactions.yml @@ -25,9 +25,14 @@ tabs: - https://www.[ENVIRONMENT]/bank-holidays pageviews: urls: - - https://[ENVIRONMENT] + - https://www.[ENVIRONMENT] - https://www.[ENVIRONMENT]/coronavirus - https://www.[ENVIRONMENT]/find-a-job +main_content_links: + class: + - 'main a' + urls: + - https://www.[ENVIRONMENT] random: urls: - https://www.[ENVIRONMENT]/random From 343cca82b239214ea9f8a1b657fcabf04a563e20 Mon Sep 17 00:00:00 2001 From: AshGDS <8880610+AshGDS@users.noreply.github.com> Date: Wed, 22 Nov 2023 15:44:53 +0000 Subject: [PATCH 3/4] Add VPN message to 'See all GA4 events' page --- app/views/developer/index.html.erb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/developer/index.html.erb b/app/views/developer/index.html.erb index 6776666..bdcf702 100644 --- a/app/views/developer/index.html.erb +++ b/app/views/developer/index.html.erb @@ -5,6 +5,7 @@

See all GA4 events for a given page

This page shows all the possible GA4 events for a given URL. This is a work in progress - only a few interactions are implemented.

Currently, this works by loading a page, and clicking every element with data-ga4-event, data-ga4-link, or data-ga4-form (with some JS to prevent default behaviour.)

+

Connect to the developer VPN to test on staging/integration environments.

<%= form_with url: runner_path, method: :post do |form| %>
<%= form.label :url, class: "govuk-label" %> From 407249f69d09cb82d7c384426f0320b582552a2b Mon Sep 17 00:00:00 2001 From: AshGDS <8880610+AshGDS@users.noreply.github.com> Date: Wed, 22 Nov 2023 15:55:55 +0000 Subject: [PATCH 4/4] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index ddebe59..f153f99 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,13 @@ bundle exec yarn install - Download both `chrome` AND `chromedriver` from https://googlechromelabs.github.io/chrome-for-testing/ - you'll want the `mac-arm64` version if you're on an M1 Mac. + +![chrome1](https://github.com/gclssvglx/analytics-robot/assets/8880610/be5db406-8248-49d3-819e-a5a04b1fe7fd) + +![chrome2](https://github.com/gclssvglx/analytics-robot/assets/8880610/1bf5b037-cfba-46af-a1d0-e415e08b01c6) + + + - Extract the zip file for `chrome` by double clicking the downloaded file. - Open your terminal, and go to the folder where Chrome was extracted, e.g. `~/Downloads/chrome-mac-arm64` - Run `sudo xattr -cr 'Google Chrome for Testing.app'`. This removes Apple's security, which prevents files that originated from zip files from being executed.