UNPKG

clarity-js

Version:

An analytics library that uses web page interactions to generate aggregated insights

140 lines (120 loc) 6.95 kB
import { assert } from 'chai'; import { Browser, Page } from 'playwright'; import { changes, clicks, inputs, launch, markup, node, text } from './helper'; import { decode } from "clarity-decode"; let browser: Browser; let page: Page; describe('Core Tests', () => { before(async () => { browser = await launch(); }); beforeEach(async () => { page = await browser.newPage(); await page.goto('about:blank'); }); afterEach(async () => { await page.close(); }); after(async () => { await browser.close(); browser = null; }); it('should mask sensitive content by default', async () => { let encoded: string[] = await markup(page, "core.html"); let decoded = encoded.map(x => decode(x)); let heading = text(decoded, "one"); let address = text(decoded, "two"); let email = node(decoded, "attributes.id", "eml"); let password = node(decoded, "attributes.id", "pwd"); let search = node(decoded, "attributes.id", "search"); let card = node(decoded, "attributes.id", "cardnum"); let option = text(decoded, "option1"); let textarea = text(decoded, "textarea"); let click = clicks(decoded)[0]; let input = inputs(decoded)[0]; let group = changes(decoded); // Non-sensitive fields continue to pass through with sensitive bits masked off assert.equal(heading, "Thanks for your order #▫▪▪▫▫▫▪▪"); // Sensitive fields, including input fields, are randomized and masked assert.equal(address, "•••••• ••••• ••••• ••••• ••••• •••••"); assert.equal(email.attributes.value, "••••• •••• •••• ••••"); assert.equal(password.attributes.value, "••••"); assert.equal(search.attributes.value, "••••• •••• ••••"); assert.equal(card.attributes.value, "•••••"); assert.equal(textarea, "••••• •••••"); assert.equal(option, "• •••••"); // Clicked text and input value should be consistent with uber masking configuration assert.equal(click.data.text, "Hello ▪▪▪▫▪"); assert.equal(input.data.value, "••••• •••• •••• ••••"); assert.equal(group.length, 2); // Search change - we should captured mangled input and hash assert.equal(group[0].data.type, "search"); assert.equal(group[0].data.value, "••••• •••• •••• ••••"); assert.equal(group[0].data.checksum, "4y7m6"); // Password change - we should capture placholder value and empty hash assert.equal(group[1].data.type, "password"); assert.equal(group[1].data.value, "••••"); assert.equal(group[1].data.checksum, ""); }); it('should mask all text in strict mode', async () => { let encoded: string[] = await markup(page, "core.html", { content: false }); let decoded = encoded.map(x => decode(x)); let heading = text(decoded, "one"); let address = text(decoded, "two"); let email = node(decoded, "attributes.id", "eml"); let password = node(decoded, "attributes.id", "pwd"); let search = node(decoded, "attributes.id", "search"); let card = node(decoded, "attributes.id", "cardnum"); let click = clicks(decoded)[0]; let input = inputs(decoded)[0]; let option = text(decoded, "option1"); // All fields are randomized and masked assert.equal(heading, "• ••••• ••••• ••••• ••••• •••••"); assert.equal(address, "•••••• ••••• ••••• ••••• ••••• •••••"); assert.equal(email.attributes.value, "••••• •••• •••• ••••"); assert.equal(password.attributes.value, "••••"); assert.equal(search.attributes.value, "••••• •••• ••••"); assert.equal(card.attributes.value, "•••••"); assert.equal(option, "• •••••"); // Clicked text and input value should also be masked in strict mode assert.equal(click.data.text, "••••• •••• ••••"); assert.equal(input.data.value, "••••• •••• •••• ••••"); }); it('should unmask non-sensitive text in relaxed mode', async () => { let encoded: string[] = await markup(page, "core.html", { unmask: ["body"] }); let decoded = encoded.map(x => decode(x)); let heading = text(decoded, "one"); let address = text(decoded, "two"); let email = node(decoded, "attributes.id", "eml"); let password = node(decoded, "attributes.id", "pwd"); let search = node(decoded, "attributes.id", "search"); let card = node(decoded, "attributes.id", "cardnum"); let click = clicks(decoded)[0]; let input = inputs(decoded)[0]; let option = text(decoded, "option1"); // Text flows through unmasked for non-sensitive fields, with exception of input fields assert.equal(heading, "Thanks for your order #2AB700GH"); assert.equal(address, "1 Microsoft Way, Redmond, WA - 98052"); assert.equal(search.attributes.value, "••••• •••• ••••"); assert.equal(option, "• •••••"); // Sensitive fields are still masked assert.equal(email.attributes.value, "••••• •••• •••• ••••"); assert.equal(password.attributes.value, "••••"); assert.equal(card.attributes.value, "•••••"); // Clicked text comes through unmasked in relaxed mode but input is still masked assert.equal(click.data.text, "Hello Wor1d"); assert.equal(input.data.value, "••••• •••• •••• ••••"); }); it('should respect mask config even in relaxed mode', async () => { let encoded: string[] = await markup(page, "core.html", { mask: ["#mask"], unmask: ["body"] }); let decoded = encoded.map(x => decode(x)); let subtree = text(decoded, "child"); let click = clicks(decoded)[0]; let input = inputs(decoded)[0]; // Masked sub-trees continue to stay masked assert.equal(subtree, "••••• •••••"); // Clicked text is masked due to masked configuration and input value is also masked assert.equal(click.data.text, "••••• •••• ••••"); assert.equal(input.data.value, "••••• •••• •••• ••••"); }); });