Skip to content

Uses Puppeteer and Jest to Audit a W3C Datalayer Implementation against patterns defined in a Data Dictionary

Notifications You must be signed in to change notification settings

cssimsek/datalayer-audit-puppeteer-jest

Repository files navigation

Data Layer Auditor (Puppeteer & Jest)

Purpose

I've found that folks involved in web (and mobile) analytics implementation still tend to test data layer implementations manually. This usually involves walking through a web journey (often manually), firing up the console and checking the state of a data layer (values assigned to properties). With a simple non-nested data layer with few data points perhaps this approach might suffice, but with complex nested w3c style data layers it is tedious and very error prone. Hence I decided to build this tool using Puppeteer and Jest to help myself and perhaps others with this task. Of course this can only be bolierplated to a certain degree as web journeys differ greatly. But the architecture attempts to offer flexibility.

How to Use

You'll first need to git clone and then npm install to install all the required packages - in particular Puppeteer and Jest (along with their dependencies).

The example setup will navigate to a particular ecommerce site and walk through some example steps while capturing the state of a w3c datalayer throughout the flow. The initial navigation is driven by the definitions in ./targets/targeturls.json

The captured data dictionary which is defined in ./targets/targetdataobjects.json is recursively flattened until it matches the format 'keyNameString': 'somePrimitive'. The values found assigned to the flattened kayNameString properties are then tested against RegExp's defined in a data dictionary xlsx file which is pulled in by the readspreadsheet.js function.

Data Dictionary

The data dictionary for the example setup looks like the table below (the RegExp's could of course be modified / improved). Here's the Google Sheet that contains this example. To create your own data dictionary you can copy the sheet, use one of these gists (JS or Node.js) to flatten your nested W3C data layer to match the expected format and define your patterns for the Key and Values. Your data dictionary should then be added to the ./datadictionary directory in .xlsx format.

DataLayer_Property_Flat Key_Pattern Type Value_Pattern Example_Value Nullable Description
digitalData_component_0_componentInfo_componentID digitalData_component_\d+_componentInfo_componentID$ string [0-9\_a-zA-Z]+[a-zA-Z0-9]$ 1155033_R_Z001A FALSE
digitalData_component_0_componentInfo_componentType digitalData_component_\d+_componentInfo_componentType$ string [a-zA-Z0-9\_]+ images FALSE
digitalData_components_0_grouping_desc digitalData_components_\d+_grouping_desc$ string ^([A-Z]{0,1}[a-z]*\s{0,})+[a-z]$ Category Product Grid FALSE
digitalData_components_0_grouping_type digitalData_components_\d+_grouping_type$ string ^GL\d+$ GL0044 FALSE
digitalData_components_desc digitalData_components_desc$ string ^([A-Z]{0,1}[a-z]*\s{0,})+[a-z]$ Hero with caps subhead FALSE
digitalData_components_id digitalData_components_id$ int \d+ 8686691 FALSE
digitalData_components_type digitalData_components_type$ string ^T\d+$ M0012 FALSE
digitalData_currentTrackValue digitalData_currentTrackValue$ string [a-z\-]+ ui-cms FALSE
digitalData_currentTrackValue digitalData_currentTrackValue$ string [a-zA-Z0-9\_]+ pdp_recommendationsNewPageViewed FALSE
digitalData_event_0_attributes_recommendations_displayedList_0 digitalData_event_\d+_attributes_recommendations_displayedList_\d+$ int \d+ 7507283 FALSE
digitalData_event_0_attributes_recommendations_fullList_0 digitalData_event_\d+_attributes_recommendations_fullList_\d+$ int \d+ 7507283 FALSE
digitalData_event_0_attributes_recommendations_source digitalData_event_\d+_attributes_recommendations_source$ string ^([A-Z]{0,1}[a-z]*\s{0,})+[a-z]$ monetisation FALSE
digitalData_event_0_attributes_recommendations_title digitalData_event_\d+_attributes_recommendations_title$ string ^([A-Z]{0,1}[a-z]*\s{0,})+[a-z]$ Featured products FALSE
digitalData_event_0_eventInfo_eventAction digitalData_event_\d+_eventInfo_eventAction$ string ^([A-Z]{0,1}[a-z]*\s{0,})+[a-z]$ Recommendations New Page Viewed FALSE
digitalData_event_0_eventInfo_eventName digitalData_event_\d+_eventInfo_eventName$ string [a-zA-Z0-9\_]+ pdp_recommendationsNewPageViewed FALSE
digitalData_event_0_eventInfo_eventRef digitalData_event_\d+_eventInfo_eventRef$ string [a-zA-Z0-9\_]+ hD7id FALSE
digitalData-event-2-attributes-link digitalData-event-\d+-attributes-link$ string ^([a-zA-Z&]\s{0,})+$ Questions & Answers FALSE
digitalData_experiments_0_experimentInfo_experimentCookie digitalData_experiments_\d+_experimentInfo_experimentCookie$ string [a-zA-Z0-9\_]+ PDP_Test_Group_1 FALSE
digitalData_experiments_0_experimentInfo_experimentName digitalData_experiments_\d+_experimentInfo_experimentName$ string [a-zA-Z\-]+ OPT-224 FALSE
digitalData_experiments_0_experimentInfo_experimentVariant digitalData_experiments_\d+_experimentInfo_experimentVariant$ .* .* null TRUE
digitalData_page_attributes_channel digitalData_page_attributes_channel$ string (?:[^:]+:?)+ uk:desktop FALSE
digitalData_page_attributes_numberOfStoresOffered digitalData_page_attributes_numberOfStoresOffered$ int \d+ 0 FALSE
digitalData_page_attributes_numberOfStoresWithInStock digitalData_page_attributes_numberOfStoresWithInStock$ int \d+ 0 FALSE
digitalData_page_attributes_numberOfStoresWithLeadTime digitalData_page_attributes_numberOfStoresWithLeadTime$ int \d+ 0 FALSE
digitalData_page_attributes_numberOfStoresWithOutOfStock digitalData_page_attributes_numberOfStoresWithOutOfStock$ int \d+ 0 FALSE
digitalData_page_attributes_platform digitalData_page_attributes_platform$ string ^([a-z]+(\_{0,1}[a-z])+?$)+$ react_magnolia FALSE
digitalData_page_attributes_platform digitalData_page_attributes_platform$ string ^([a-z0-9]+\_?)+ react_pdp FALSE
digitalData_page_attributes_specialOffersIDs_0 digitalData_page_attributes_specialOffersIDs_\d+$ string ^[A-Z]{1}\d+$ E30182 FALSE
digitalData_page_attributes_specialOffersNumber digitalData_page_attributes_specialOffersNumber$ int \d+ 3 FALSE
digitalData_page_attributes_specialOffersTypes_0 digitalData_page_attributes_specialOffersTypes_\d+$ string [a-zA-Z]+\b isBuilderOffer FALSE
digitalData_page_attributes_templateDesc digitalData_page_attributes_templateDesc$ string ^[A-Z]{1}[a-z]+$ Hybrid FALSE
digitalData_page_attributes_templateId digitalData_page_attributes_templateId$ string ^T\d+$ T013 FALSE
digitalData_page_category_pageType digitalData_page_category_pageType$ string ^[a-z]+$ events FALSE
digitalData_page_category_pageType digitalData_page_category_pageType$ string [a-zA-Z]+\b pdp FALSE
digitalData_page_category_subCategory3 digitalData_page_category_subCategory\d+$ string ^([A-Z]{0,1}[a-z]*\s{0,})+[a-z]$ SIM free phones FALSE
digitalData_page_pageInfo_categoryID_0 digitalData_page_pageInfo_categoryID_\d+$ int \d+ 29949 FALSE
digitalData_page_pageInfo_pageName digitalData_page_pageInfo_pageName$ string ^([a-z0-9-]+:)+$ ar:pdp:1155033:simfreegooglepixel3a64gbmobilephone-white: FALSE
digitalData_page_pageInfo_siteSection digitalData_page_pageInfo_siteSection$ string ^([a-z0-9]+:)+$ ar:events: FALSE
digitalData_parallelRun digitalData_parallelRun$ boolean .* TRUE FALSE
digitalData_product_0_attributes_alternativesStore digitalData_product_\d+_attributes_alternativesStore$ object .* null FALSE
digitalData_product_0_attributes_brandRangeLink digitalData_product_\d+_attributes_brandRangeLink$ string ^([A-Z]{0,1}[a-z]*\s{0,})+[a-z]$ Google FALSE
digitalData_product_0_attributes_cnetContent digitalData_product_\d+_attributes_cnetContent$ boolean .* TRUE FALSE
digitalData_product_0_attributes_collectionStockCode digitalData_product_\d+_attributes_collectionStockCode$ int \d+ 5 FALSE
digitalData_product_0_attributes_collectionStockLevelMessage digitalData_product_\d+_attributes_collectionStockLevelMessage$ object .* null TRUE
digitalData_product_0_attributes_collectionStoreType digitalData_product_\d+_attributes_collectionStoreType$ string ^([A-Z]{0,1}[a-z]*\s{0,})+[a-z]$ regular FALSE
digitalData_product_0_attributes_existingProductOptions digitalData_product_\d+_attributes_existingProductOptions$ object .* null TRUE
digitalData_product_0_attributes_fastTrackBanner digitalData_product_\d+_attributes_fastTrackBanner$ string ([^:]+\b) pdp:banner:fastTrack FALSE
digitalData_product_0_attributes_fulfillmentMethod digitalData_product_\d+_attributes_fulfillmentMethod$ string [a-z]+(|[a-z]+)? collection delivery FALSE
digitalData_product_0_attributes_numberOfAnswers digitalData_product_\d+_attributes_numberOfAnswers$ int \d+ 3 FALSE
digitalData_product_0_attributes_numberOfQuestions digitalData_product_\d+_attributes_numberOfQuestions$ int \d+ 3 FALSE
digitalData_product_0_attributes_numberOfReviews digitalData_product_\d+_attributes_numberOfReviews$ int \d+ 5 FALSE
digitalData_product_0_attributes_priceMessage digitalData_product_\d+_attributes_priceMessage$ string ^([A-Z]{0,1}[a-z]*\s{0,})+[a-z]$ TRUE
digitalData_product_0_attributes_promotion digitalData_product_\d+_attributes_promotion$ boolean .* FALSE FALSE
digitalData_product_0_attributes_selectedProductOptions digitalData_product_\d+_attributes_selectedProductOptions$ object .* null TRUE
digitalData_product_0_attributes_starRating digitalData_product_\d+_attributes_starRating$ float \d+.\d+ 4.8 FALSE
digitalData_product_0_attributes_storeID digitalData_product_\d+_attributes_storeID$ object .* null TRUE
digitalData_product_0_attributes_unitPriceWithTax digitalData_product_\d+_attributes_unitPriceWithTax$ int \d+ 399 FALSE
digitalData_product_0_productInfo_productID digitalData_product_\d+_productInfo_productID$ int \d+ 1155033 FALSE
digitalData_product_0_productInfo_productName digitalData_product_\d+_productInfo_productName$ string ^([a-zA-Z0-9]+[\s-]*)+$ SIM Free Google Pixel 3a 64GB Mobile Phone - White FALSE
digitalData_trackVersion digitalData_trackVersion$ string ^(ut)(\d{12})? utag.js FALSE Possibly should be looking for utag.cfg.v? ut4.45.201906201435
digitalData_trackVersion digitalData_trackVersion$ string ([a-z.]*)\b utag.js FALSE
digitalData_user_0_profile_0_attributes_globalView digitalData_user_\d+_profile_\d+_attributes_globalView$ boolean .* TRUE FALSE
digitalData_user_0_profile_0_attributes_loginStatus digitalData_user_\d+_profile_\d+_attributes_loginStatus$ string [a-zA-Z-]+$ Non-Registered FALSE
digitalData_user_profile_attributes_loginStatus digitalData_user_profile_attributes_loginStatus$ string ^[A-Z]{1}[a-z]+$ Registered FALSE
digitalData_user_profile_profileInfo_profileID digitalData_user_profile_profileInfo_profileID$ string .* " TRUE

About

Uses Puppeteer and Jest to Audit a W3C Datalayer Implementation against patterns defined in a Data Dictionary

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published