Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ash changes #21

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,29 @@ 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)
- 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.

- 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`
![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.
- 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

Expand Down
53 changes: 38 additions & 15 deletions app/controllers/developer_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion app/controllers/home_controller.rb
Original file line number Diff line number Diff line change
@@ -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]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I swapped these around, just so that integration is the default option on the form - so production isn't spammed with data

end

def fake
Expand Down
19 changes: 18 additions & 1 deletion app/javascript/channels/developer_channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand Down Expand Up @@ -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 += '<details><summary>' + summary + '</summary>' + this.prettyPrint(dataLayerEvents[i]) + '</details>'
}

pre.append(code)
div.append(pre)
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/channels/faker_channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: <details class="govuk-details" data-module="govuk-details">'
dataDisplay += '<summary class="govuk-details__summary">'
dataDisplay += '<span class="govuk-details__summary-text">'
Expand Down
9 changes: 9 additions & 0 deletions app/models/fake_events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion app/models/gtm_event_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions app/views/developer/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<div class="govuk-grid-column-full">
<h1 class="govuk-heading-xl">See all GA4 events for a given page </h1>
<p class="govuk-body">This page shows all the possible GA4 events for a given URL. This is a work in progress - only a few interactions are implemented.<p>
<p class="govuk-body">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.)<p>
<p class="govuk-body"><strong>Connect to the developer VPN to test on staging/integration environments.</strong></p>
<%= form_with url: runner_path, method: :post do |form| %>
<div class="govuk-form-group">
<%= form.label :url, class: "govuk-label" %>
Expand Down
4 changes: 3 additions & 1 deletion app/views/home/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-xl">Analytics Robot</h1>
<h2 class="govuk-heading-m">Run our automated GA4 tests on an environment</h2>
<p class="govuk-body">This form will run any tests listed in interactions.yaml on the chosen environment</p>
<p class="govuk-body">This form will run any tests listed in interactions.yaml on the chosen environment.</p>
<p class="govuk-body"><strong>Connect to the developer VPN to test on staging/integration environments.</strong></p>

<%= form_with url: fake_path, method: :post do |form| %>
<div class="govuk-form-group">
<%= form.label :environment, class: "govuk-label" %>
Expand Down
13 changes: 9 additions & 4 deletions data/interactions.yml
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -19,15 +19,20 @@ 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
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