Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/consent/consent-tools-integration-tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ yarn . test:int
### Debugging Tips:
- Webdriver.io has the handy `browser.debug()` command.

- You can serve the static pages by themselves (without webdriver.io) with the following:
- You can serve the static pages by themselves (without Playwright) with the following:
```
yarn webpack -w &
npx live-server .
Expand Down
17 changes: 6 additions & 11 deletions packages/consent/consent-tools-integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,28 @@
"private": true,
"scripts": {
".": "yarn run -T turbo run --filter=@internal/consent-tools-integration-tests...",
"test:int": "yarn wdio:local",
"test:int": "playwright test",
"test:int-debug": "playwright test --debug",
"build": "webpack",
"watch": "yarn build --watch",
"wdio:local": "wdio wdio.conf.local.ts",
"lint": "yarn concurrently 'yarn:eslint .' 'yarn:tsc --noEmit'",
Copy link
Contributor

@silesky silesky Apr 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Can we remove all the old wdio dependencies?
  2. Can we update/commit the yarn.lock? (CI is failing)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor Author

@neelkanth-kaushik neelkanth-kaushik Apr 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI is still failing after pushing yarn.lock. I will look into it separately once all the test cases have been migrated.

"eslint": "yarn run -T eslint",
"tsc": "tsc",
"concurrently": "yarn run -T concurrently --raw"
"concurrently": "yarn run -T concurrently --raw",
"serve": "http-server --port 5432"
},
"installConfig": {
"hoistingLimits": "workspaces"
},
"devDependencies": {
"@internal/test-helpers": "workspace:^",
"@playwright/test": "^1.28.1",
"@segment/analytics-consent-tools": "workspace:^",
"@segment/analytics-consent-wrapper-onetrust": "workspace:^",
"@segment/analytics-next": "workspace:^",
"@wdio/cli": "^8.10.6",
"@wdio/devtools-service": "^8.10.6",
"@wdio/local-runner": "^8.10.6",
"@wdio/mocha-framework": "^8.10.6",
"@wdio/spec-reporter": "^8.10.6",
"@wdio/static-server-service": "^8.10.6",
"@wdio/types": "8",
"expect": "^29.4.1",
"globby": "^11.0.2",
"wdio-intercept-service": "^4.4.0",
"http-server": "14.1.1",
"webpack": "^5.94.0",
"webpack-cli": "^4.8.0"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { PlaywrightTestConfig } from '@playwright/test'
import { devices } from '@playwright/test'
import path from 'path'

/**
* See https://playwright.dev/docs/test-configuration.
*/
const config: PlaywrightTestConfig = {
webServer: {
command: 'yarn serve',
url: 'http://127.0.0.1:5432',
reuseExistingServer: !process.env.CI,
},
testDir: './src/tests',
globalSetup: path.resolve(__dirname, 'playwright.global-setup.ts'),
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000,
},
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: [['html', { open: 'never' }]],
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
baseURL: `http://127.0.0.1:5432`,
trace: 'on',
launchOptions: {
args: ['--enable-precise-memory-info', '--js-flags=--expose-gc'],
},
},

/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
},
},
],
}

export default config
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { FullConfig } from '@playwright/test'
import { execSync } from 'child_process'

export default function globalSetup(_cfg: FullConfig) {
console.log('Executing global setup...')
execSync('yarn build', { stdio: 'inherit' })
console.log('Finished global setup.')
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<script src="https://cdn.cookielaw.org/scripttemplates/otSDKStub.js" type="text/javascript" charset="UTF-8"
data-domain-script="80ca7b5c-e72f-4bd0-972a-b74d052a0820-test"></script>

<script src="/node_modules/@segment/analytics-consent-wrapper-onetrust/dist/umd/analytics-onetrust.umd.js"></script>

<script>
<!-- <script src="/node_modules/@segment/analytics-consent-wrapper-onetrust/dist/umd/analytics-onetrust.umd.js"></script> -->
<script src="dist/onetrust.bundle.js"></script>
<!-- <script>
!(function () {
var analytics = (window.analytics = window.analytics || [])
if (!analytics.initialize)
Expand Down Expand Up @@ -67,7 +67,7 @@
analytics.page()
}
})()
</script>
</script> -->
</head>

<body>
Expand All @@ -76,4 +76,4 @@ <h2>Please Check Network tab</h2>
<p>This page can used as playground or run by webdriver.io</p>
</body>

</html>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
<body>
<h1>Hello World - Serving Analytics</h1>
<h2>Please Check Network tab</h2>
<p>This page can used as playground or run by webdriver.io</p>
<script src="/public/dist/consent-tools-vanilla-opt-in.bundle.js"></script>
<p>This page can used as playground or run by Playwright</p>
<script src="dist/consent-tools-vanilla-opt-in.bundle.js"></script>
</body>

</html>
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
<body>
<h1>Hello World - Serving Analytics (Consent Tools Vanilla Opt Out)</h1>
<h2>Please Check Network tab</h2>
<p>This page can used as playground or run by webdriver.io</p>
<script src="/public/dist/consent-tools-vanilla-opt-out.bundle.js"></script>
<p>This page can used as playground or run by Playwright</p>
<script src="dist/consent-tools-vanilla-opt-out.bundle.js"></script>
</body>

</html>
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const analytics = new AnalyticsBrowser()

withMockCMP(analytics).load(
{
writeKey: '9lSrez3BlfLAJ7NOChrqWtILiATiycoc',
writeKey: 'foo',
},
{ initialPageview: true }
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { AnalyticsBrowser } from '@segment/analytics-next'
import { initMockConsentManager } from '../helpers/mock-cmp'
import { withMockCMP } from '../helpers/mock-cmp-wrapper'

initMockConsentManager({
consentModel: 'opt-in',
})
//import { withOneTrust } from '@segment/analytics-consent-wrapper-onetrust'

// declare global {
// interface Window {
// withOneTrust: typeof import('@segment/analytics-consent-wrapper-onetrust').withOneTrust
// }
// }
// window.withOneTrust = withOneTrust

const analytics = new AnalyticsBrowser()

withMockCMP(analytics).load(
{
writeKey: 'foo',
},
{ initialPageview: true }
)
;(window as any).analytics = analytics
Original file line number Diff line number Diff line change
@@ -1,124 +1,123 @@
import { CDNSettingsBuilder } from '@internal/test-helpers'
import type { SegmentEvent } from '@segment/analytics-next'
import assert from 'assert'
import type { Matches } from 'webdriverio'

const waitUntilReady = () =>
browser.waitUntil(
() => browser.execute(() => document.readyState === 'complete'),
{
timeout: 10000,
}
)
import { Page, Route, Request } from '@playwright/test'
import { SegmentEvent } from '@segment/analytics-next'
import { CoreExtraContext } from '@segment/analytics-core'

export abstract class BasePage {
constructor(protected page: string) {}
protected page: Page
protected pageFile: string

segmentTrackingApiReqs: Matches[] = []
fetchIntegrationReqs: Matches[] = []
segmentTrackingApiReqs: SegmentEvent[] = []
fetchIntegrationReqs: CoreExtraContext[] = []

constructor(page: Page, pageFile: string) {
this.page = page
this.pageFile = pageFile
}

async load(): Promise<void> {
const baseURL = browser.options.baseUrl
assert(baseURL)
await this.mockAPIs()
await browser.url(baseURL + '/public/' + this.page)
await waitUntilReady()
await this.page.goto(`/${this.pageFile}`)
await this.page.waitForLoadState('load')
}

async clearStorage() {
await browser.deleteAllCookies()
await browser.execute(() => window.localStorage.clear())
await this.page.context().clearCookies()
await this.page.evaluate(() => {
window.localStorage.clear()
window.sessionStorage.clear()
})
}

async cleanup() {
this.segmentTrackingApiReqs = []
this.fetchIntegrationReqs = []
await this.clearStorage()
}

getAllTrackingEvents(): SegmentEvent[] {
const reqBodies = this.segmentTrackingApiReqs.map((el) =>
JSON.parse(el.postData!)
)
return reqBodies
return this.segmentTrackingApiReqs
}

getConsentChangedEvents(): SegmentEvent[] {
const reqBodies = this.getAllTrackingEvents()
const consentEvents = reqBodies.filter(
return this.getAllTrackingEvents().filter(
(el) => el.event === 'Segment Consent Preference Updated'
)
return consentEvents
}

async cleanup() {
this.segmentTrackingApiReqs = []
this.fetchIntegrationReqs = []
await this.clearStorage()
get fetchIntegrationReqsData(): CoreExtraContext[] {
return this.fetchIntegrationReqs
}

async mockAPIs() {
protected async mockAPIs() {
await this.mockSegmentTrackingAPI()
await this.mockCDNSettingsAPI()
await this.mockNextIntegrationsAPI()
}

private async mockSegmentTrackingAPI(): Promise<void> {
const mock = await browser.mock('https://api.segment.io/v1/t', {
method: 'post',
})
mock.respond((mock) => {
this.segmentTrackingApiReqs.push(mock)
// response with status 200
return Promise.resolve({
statusCode: 200,
body: JSON.stringify({ success: true }),
})
})
private async mockSegmentTrackingAPI() {
await this.page.route(
'https://api.segment.io/v1/t',
async (route: Route, request: Request) => {
const postData = await request.postData()
const parsed = JSON.parse(postData || '{}')
this.segmentTrackingApiReqs.push(parsed) // store the parsed event object directly

await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ success: true }),
})
}
)
}

private async mockNextIntegrationsAPI(): Promise<void> {
const mock = await browser.mock('**/next-integrations/**')
mock.respond((mock) => {
this.fetchIntegrationReqs.push(mock)
return Promise.resolve({
statusCode: 200,
body: 'console.log("mocking action and classic destinations")',
})
})
private async mockNextIntegrationsAPI() {
await this.page.route(
'**/next-integrations/**',
async (route: Route, request: Request) => {
this.fetchIntegrationReqs.push({ url: request.url() })
await route.fulfill({
status: 200,
body: 'console.log("mocking action and classic destinations")',
contentType: 'application/javascript',
})
}
)
}

/** * Mock the CDN Settings endpoint so that this can run offline
*/
private async mockCDNSettingsAPI(): Promise<void> {
const settings = new CDNSettingsBuilder({
writeKey: 'something',
const cdnSettings = new CDNSettingsBuilder({
writeKey: 'foo',
})
.addActionDestinationSettings(
{
url: 'https://cdn.segment.com/next-integrations/actions/fullstory-plugins/foo.js',
creationName: 'FullStory',
url: 'https://cdn.segment.com/next-integrations/actions/fullstory-plugins/foo.js',
consentSettings: {
categories: ['FooCategory2'],
},
},
{
url: 'https://cdn.segment.com/next-integrations/actions/amplitude-plugins/foo.js',
creationName: 'Actions Amplitude',
url: 'https://cdn.segment.com/next-integrations/actions/amplitude-plugins/foo.js',
consentSettings: {
categories: ['FooCategory1'],
},
}
)
.build()

const mock = await browser.mock('**/settings')
mock.respond(settings, {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
},
await this.page.route('**/settings', async (route: Route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify(cdnSettings),
})
})
}

/**
* Hard reload the page
*/
reload() {
return browser.execute(() => window.location.reload())
async reload() {
await this.page.reload()
}
}
Loading
Loading