Skip to content

Instantly share code, notes, and snippets.

@yannbf
Last active August 11, 2021 13:43
Show Gist options
  • Save yannbf/f41cec7f91fc09f0e70024d3bc540ae4 to your computer and use it in GitHub Desktop.
Save yannbf/f41cec7f91fc09f0e70024d3bc540ae4 to your computer and use it in GitHub Desktop.
Automated scripts to make things easier for bol devs!
// ==UserScript==
// @name Bol automator
// @namespace http://tampermonkey.net/
// @version 0.13
// @description Easier, interesting ways of automating stuff to make our lives easier :D
// @author Yann Braga
// @match https://*.test2.bol.com/*
// @match https://*.acc2.bol.com/*
// @icon https://www.google.com/s2/favicons?domain=bol.com
// @updateURL https://gist.github.com/yannbf/f41cec7f91fc09f0e70024d3bc540ae4/raw/bol-scripts.user.js
// @grant none
// ==/UserScript==
const PRODUCTS = [
'Created globalId 3349663863499526 with offerId 0 (bol book under 20)',
'Created globalId 3744740617427522 with offerId 0 (bol book over 20)',
'Created globalId 3227380069545144 with offerId 0 (bol study book under 20)',
'Created globalId 3795851857073197 with offerId 0 (bol multibundle book)',
'Created globalId 3469781121149033 with offerId 0 (bol giftwrappable toy)',
'Created globalId 3321346368505775 with offerId 0 (bol non-giftwrappable toy)',
'Created globalId 3169608829076049 with offerId 0 (bol ebook)',
'Created globalId 3465675514443322 with offerId 0 (bol english ebook)',
'Created globalId 3150103937857162 with offerId 0 (bol book with select deal)',
'Created globalId 3752316248264439 with offerId 0 (bol bluray with promotion)',
'Created globalId 3836329728838881 with offerId 0 (bol washing machine)',
'Created globalId 3853538129018159 with offerId 0 (bol bluray)',
'Created globalId 3600607525362618 with offerId 0 (bol mobile phone)',
'Created globalId 3384581168835374 with offerId 0 (bol cd)',
'Created globalId 3555744534840079 with offerId 0 (bol Crossdock book over 20)',
'Created globalId 3420204574590060 with offerId 0 (letterbox eligible bol product)',
'Created globalId 3112257371784680 with offerId 0 (Test Playstation 5)',
'Created globalId 3220569753615010 with offerId 9991813523142392 (plaza FBB book)',
'Created globalId 3645878294818980 with offerId 9999151208351300 (plaza FBR book)',
'Created globalId 3572004885759651 with offerId 9999840302764228 (Secondhand book)',
'Created globalId 3499599736841425 with offerId 9991813523142392 (plaza Crossdock book over 20)',
'Created globalId 3104589923266295 with offerId 9999151208351300 (plaza FBR washing Machine)',
'Created globalId 3238322065437141 with offerId 9999151208351300 (plaza FBR washing Machine)',
'Created globalId 3712841440775452 with offerId 0 (bol NL PUP product)',
'Created globalId 3193429337418977 with offerId 0 (Bol BE PUP product)',
'Created globalId 3230782448468489 with offerId 0 (bol NL BE PUP product)',
'Created globalId 3270082141201023 with offerId 0 (bol Oversized for PUP product)',
'Created globalId 3529227847635162 with offerId 0 (Heavy product not eligible for PUP)',
'Created globalId 3067191091196040 with offerId 0 (bol chunk id not eligible for PUP product)',
'Created globalId 3733965337651471 with offerId 0 (small PUP product)',
'Created globalId 3848052438238206 with offerId 0 (Digital pre-order without release date)',
'Created globalId 3608698162024315 with offerId 0 (Digital pre-order with release date)',
'Created globalId 3941315935211562 with offerId 0 (Physical pre-order without release date)',
'Created globalId 3083587059143144 with offerId 0 (Physical pre-order with release date)',
'Created globalId 3689334845406313 with offerId 0 (bol book NL)',
'Created globalId 3616161042298180 with offerId 0 (bol software download NL)',
'Created globalId 3119787031826340 with offerId 0 (bol audiobook)',
'Created globalId 3948862707578514 with offerId 0 (bol game download NL)',
'Created globalId 3030749534273391 with offerId 9997617369995080 (plaza toy separate NL and BE offers)',
'Created globalId 3030749534273391 with offerId 9993052409248412 (plaza toy separate NL and BE offers)',
];
//// COOKIE UTILITIES ///////////////
const setCookie = (name, value, days = 1) => {
var expires = '';
if (days) {
var date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
expires = '; expires=' + date.toUTCString();
}
document.cookie = name + '=' + (value || '') + expires + '; path=/';
};
const getCookie = (name) => {
var nameEQ = name + '=';
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
};
const eraseCookie = (name) => {
document.cookie = name + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
};
const loadHelperFunctions = () => {
window.getInputByName = (name) => document.querySelector(`input[name="${name}"]`);
window.fillInput = (name, value) => {
window.getInputByName(name).value = value;
};
};
///////////////////////////////
const changeLanguage = () => {
const currentLang = getCookie('language');
if (currentLang === 'nl-NL') {
setCookie('shoppingContextChannel', 'iphoneapp');
setCookie('language', 'fr');
setCookie('locale', 'fr_BE');
} else {
eraseCookie('shoppingContextChannel');
setCookie('language', 'nl-NL');
setCookie('locale', 'NL');
}
window.location.reload();
};
const getAppVersion = () => {
fetch('/nl/internal/version.html')
.then(function (response) {
return response.text();
})
.then(function (html) {
// Convert the HTML string into a document object
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
// Get the image file
const version = doc.querySelector('.version');
alert(version.textContent);
})
.catch(function (err) {
// There was an error
console.warn('Something went wrong.', err);
});
};
const getCheckoutState = async () => {
const response = await fetch('/nl/rnwy/checkout/state');
return response.json();
};
const loadGlobalStyles = (environment) => {
const bgColor = {
FEATURE: '#e91e63',
TEST: '#ff9800',
ACC: '#009688',
};
const globalCSS = `
.wsp-header, .wsp-footer__servicebar {
background: ${bgColor[environment] || '#0000a4'};
}
.wsp-header {
position: relative;
}
.semi-hidden {
opacity: 0.1;
transition: opacity 200ms;
}
.semi-hidden:hover {
opacity: 1;
}
.wsp-header:before {
content: '${environment}';
text-shadow: 2px 2px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
position: absolute;
font-size: 1rem;
top: 0rem;
left: 0.5rem;
font-weight: 800;
color: white;
}
.bdev-product-list {
font-family: 'Graphik';
padding: 0.5rem;
background: rgb(255 255 255 / 90%);
box-shadow: rgb(149 157 165 / 20%) 0px 8px 24px;
border-radius: 1rem;
max-height: 25rem;
max-width: 10rem;
display: flex;
flex-direction: column;
overflow: auto;
overflow-x: hidden;
}
.bdev-product-list:hover {
opacity: 1;
}
.bdev-product-item {
text-transform: capitalize;
color: #2f2525;
font-weight: 600;
padding: 0.5rem 0;
}
.bdev-panel {
position: fixed;
right: 1rem;
bottom: 1rem;
}
.bdev-buttons {
z-index: 2;
display: flex;
flex-direction: column;
align-items: flex-end;
}
.bdev-buttons .ui-btn {
margin-left: 0;
margin-bottom: 0.25rem;
width: 8rem;
}
.ui-btn--fallback {
display: inline-flex;
flex-wrap: nowrap;
flex-shrink: 0;
position: relative;
margin: 0;
background-color: transparent;
background-image: none;
align-items: center;
justify-content: center;
border: 1px solid transparent;
padding: 0 calc(1rem - 1px);
line-height: calc(3rem - 2px);
height: 3rem;
overflow: hidden;
vertical-align: middle;
text-align: center;
text-decoration: none;
white-space: nowrap;
font-size: 14px;
font-weight: 400;
user-select: none;
background-color: #00f;
border-color: #00f;
color: #fff;
box-shadow: 0 4px 0 -2px rgba(10,10,10,.25);
margin-left: 0.5rem;
}
`;
const style = document.createElement('style');
if (style.styleSheet) {
style.styleSheet.cssText = globalCSS;
} else {
style.appendChild(document.createTextNode(globalCSS));
}
document.getElementsByTagName('head')[0].appendChild(style);
};
const loadAutoBuyCertificate = () => {
if (!location.href.includes('digitale-cadeaubon')) return;
const autoBuyCertificate = () => {
// Auto gift certificate buy
document.querySelector('.select-grid__item').click();
window.fillInput('receiver-name', 'Billie');
window.fillInput('receiver-email', 'Billie@test.bol.com');
document.querySelector('textarea[name="message"]').value = 'You deserve it :)';
window.fillInput('sender-name', 'Billie sender');
window.fillInput('sender-email', 'test@test.bol.com');
document.querySelector('input[type="submit"]').click();
};
const UI = document.createElement('button');
UI.textContent = 'Auto-buy gift card';
UI.className = 'ui-btn--fallback';
UI.addEventListener('click', autoBuyCertificate);
document.querySelector('.breadcrumbs').appendChild(UI);
};
const loadAutoFillAccountCreation = () => {
if (!location.href.includes('account/register.html')) return;
const autoFillForm = () => {
// Auto gift certificate buy
document.querySelector('input[type=radio]').click();
window.fillInput('firstName', 'Billie');
window.fillInput('lastName', 'Test');
window.fillInput('address.zipCode', '1092CP');
window.fillInput('address.houseNumberWithExtension', '96');
window.fillInput('phoneNumber', '06111111111');
window.fillInput('account_password', 'boltest');
document.querySelector('input[name=account_password]').type = 'text';
document.querySelector('button[name=send]').click();
};
const UI = document.createElement('button');
UI.textContent = 'Auto-fill form';
UI.className = 'ui-btn--fallback';
UI.addEventListener('click', autoFillForm);
document.querySelector('#account-aanmaken').parentElement.prepend(UI);
};
const changeElementTextInABit = (element, originalText) => {
setTimeout(() => {
element.textContent = originalText
}, 1000)
}
(function () {
'use strict';
const isFeatureEnv = location.href.includes('feature');
const isAcc = location.href.includes('acc2');
const isTest = location.href.includes('test2');
const isLegacyOCP = location.href.includes('paid');
const isNewOCP = location.href.includes('order-confirmation');
const isCheckout = location.href.includes('checkout');
const isInternalToolingPage = location.href.includes('internal') || location.href.includes('_pages');
if (isInternalToolingPage) return;
const environment = isFeatureEnv ? 'FEATURE' : isTest ? 'TEST' : isAcc ? 'ACC' : '';
loadHelperFunctions();
loadGlobalStyles(environment);
loadAutoBuyCertificate();
loadAutoFillAccountCreation();
// we don't want overlaying stuff on mobile, it's too cluttered
const isMobile = window.matchMedia('only screen and (max-width: 600px)').matches;
if (isMobile) return;
const Panel = document.createElement('div');
Panel.className = 'bdev-panel';
if (!isAcc) {
const FloatingBasket = document.createElement('ul');
FloatingBasket.className = 'bdev-product-list semi-hidden';
PRODUCTS.forEach((product) => {
const [, globalId, offerId, productName] = product.match(
/Created globalId ([0-9]*) with offerId ([0-9]*) \((.*)\)/,
);
const ProductLink = document.createElement('a');
ProductLink.textContent = productName;
ProductLink.href = `${location.origin}/nl/order/basket/addItems.html?productId=${globalId}&offerId=${offerId}&quantity=1`;
ProductLink.className = 'bdev-product-item c-link';
FloatingBasket.appendChild(ProductLink);
});
Panel.appendChild(FloatingBasket);
}
const ButtonGroup = document.createElement('div');
ButtonGroup.className = 'bdev-buttons';
setTimeout(() => {
// if there's Krux, we can get taxonomy info
if (window.Krux) {
const Krux = document.createElement('button');
Krux.className = 'ui-btn ui-btn--primary semi-hidden';
Krux.textContent = 'copy krux';
Krux.addEventListener('click', async () => {
const textToCopy = JSON.stringify(window.Krux.taxonomy, null, 2);
await navigator.clipboard.writeText(textToCopy);
Krux.textContent = 'copied!';
});
ButtonGroup.appendChild(Krux);
}
}, 1000);
const AppVersion = document.createElement('button');
AppVersion.className = 'ui-btn ui-btn--primary semi-hidden';
AppVersion.textContent = 'App version';
AppVersion.addEventListener('click', getAppVersion);
ButtonGroup.appendChild(AppVersion);
const ToggleLanguage = document.createElement('button');
ToggleLanguage.className = 'ui-btn ui-btn--primary semi-hidden';
ToggleLanguage.textContent = 'Toggle language';
ToggleLanguage.addEventListener('click', () => changeLanguage('fr'));
ButtonGroup.appendChild(ToggleLanguage);
if (isNewOCP) {
const Payload = document.createElement('button');
Payload.className = 'ui-btn ui-btn--primary semi-hidden';
Payload.textContent = 'copy payload';
Payload.addEventListener('click', async () => {
const thePayload = document.querySelector('[data-payload-id="order-confirmation"]');
const textToCopy = JSON.stringify(JSON.parse(thePayload.textContent), null, 2);
await navigator.clipboard.writeText(textToCopy);
Payload.textContent = 'copied!';
changeElementTextInABit(Payload, 'copy payload');
});
ButtonGroup.appendChild(Payload);
}
if (isCheckout) {
const Payload = document.createElement('button');
Payload.className = 'ui-btn ui-btn--primary semi-hidden';
Payload.textContent = 'copy state';
Payload.addEventListener('click', async () => {
const thePayload = await getCheckoutState();
const textToCopy = JSON.stringify(thePayload, null, 2);
await navigator.clipboard.writeText(textToCopy);
Payload.textContent = 'copied!';
changeElementTextInABit(Payload, 'copy state');
});
ButtonGroup.appendChild(Payload);
}
Panel.appendChild(ButtonGroup);
document.body.appendChild(Panel);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment