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.
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.
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]$ | 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 |