Posted: 2024-01-06
Warning: Technical content inside 😉
Service Worker is a JavaScript that your browser runs in the background. It is not part of the web page, rather it allows to add additional features like push notifications or background synchronization.
Browser enforces very strong security mechanism around service worker: - script can only be started from a https or localhost urls - no code can be injected from web page - service worker is not allowed to access DOM directly - service worker can communicate with web pages it controls by responding to messages sent via postMessage api
Protections around code injection makes testing of service workers complicated, however Puppeteer is a tool that can help with that. Puppeteer communicates with Chrome browser via Chrome DevTools Protocol - CDP. This means we have access to networking events.
The easy way with setRequestInterception unfortunately does not work reliably with service workers. They operate in a different target context so we need to use CDP directly.
The following code snippet shows how to do this:
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('https://example.com')
browser.on('targetcreated', async (target) => {
const client = await target.createCDPSession()
await client.send('Network.enable')
client.on('Network.requestWillBeSent', params => {
console.log( 'target: ', target.name, 'params: ', params)
}
}
We register a callback which puppeteer will call when a new target is created (example: a new page or new service worker). Then we register another callback on CDP client with method Network.requestWillBeSent which allows us to inspect traffic from Service Worker and perform necessary testing activities.
Hurray! We have achieved state of inception: a callback in a callback aka callback-hell.
Photo by pixpoetry on Unsplash
Posted: 2023-12-10
As known as: Generating test data.
Here at Process IQ we are obsessed with automated testing to ensure our customers get top notch products and service. We do all of them: unit testing, integration testing, regression testing and performance testing. Some times we even test our test tools to ensure that they are good at testing (whew! that was a mouthful).
One of the challenges in modern software business is getting a sensible test data. This is especially important for performance testing where data needs to be generated in order to saturate the system to ensure it works well under normal conditions.
One of the techniques we like is to use Faker.js. This is a Node/Javascript package which simplifies creating meaningful names and content. Code for this post is on our Github repo.
The essential part of the code is below. It consist effectively of four parts: open connection to Postgresql, create table, generate data and perform insert. Final names actually look pretty good.
// create client
const client = new PG.Client({ connectionString: process.env.DB_CONNECTION_STRING })
// connect
await client.connect()
// create table
await client.query(sql)
// generate data
const arr = _.range(numRecords).map(i => {
const rc = faker.helpers.createCard()
return {
name: rc.company.name,
business: rc.company.bs,
phone: rc.phone,
address: rc.address.streetA + ', ' + rc.address.streetB + ', ' + rc.address.zipcode + ' ' + rc.address.city + ', ' + rc.address.county
}
}).map(x => [x.name, x.business, x.phone, x.address])
// perform insert
const insertSql = format('insert into counterparties( name, business, phone, address) values %L returning id', arr)
const res = await client.query(insertSql)
Photo by Sergey Semin on Unsplash