Skip to content
Open
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
4 changes: 3 additions & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ jobs:
allowed-endpoints:
1.gravatar.com:443
1.gravatar.com:80
140.82.114.22:443
2.gravatar.com:443
2.gravatar.com:80
api.github.com:443
Expand Down Expand Up @@ -98,6 +97,9 @@ jobs:
- name: Install VIP CLI
run: npm install -g @automattic/vip

- name: Pin local dev-env hostname
run: echo "127.0.0.1 e2e-agentforce-test-site.vipdev.lndo.site" | sudo tee -a /etc/hosts

- name: Determine WP version
run: |
if [ -z "${{ github.event.inputs.wpversion }}" ]; then
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ jobs:
- name: Install dependencies
run: npm ci

- name: Build JS assets
run: npm run build:js

- uses: php-actions/composer@v6
with:
php_version: "${{ matrix.config.php }}"
Expand Down
46 changes: 39 additions & 7 deletions assets/src/js/cmp-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,54 @@
*/
const getEmbeddingConfig = () => window.vipAgentforceConsentData?.embedding;
const getPrechatFields = () => window.vipAgentforceConsentData?.prechatFields;
let onEmbeddedMessagingReadyHandler;

const setupEmbeddedMessagingReadyHandler = () => {
if (onEmbeddedMessagingReadyHandler) {
return;
}

onEmbeddedMessagingReadyHandler = () => {
const settings = window.embeddedservice_bootstrap?.settings;
if (!settings) {
return;
}

settings.restrictSessionOnMessagingChannel = true;

const setupPrechatFields = () => {
window.addEventListener('onEmbeddedMessagingReady', () => {
const prechatFields = getPrechatFields();
if (!prechatFields || Object.keys(prechatFields).length === 0) {
const hasPrechatFields =
prechatFields && Object.keys(prechatFields).length > 0;

if (!hasPrechatFields) {
return;
}

try {
window.embeddedservice_bootstrap.settings.restrictSessionOnMessagingChannel = true;
window.embeddedservice_bootstrap.prechatAPI.setHiddenPrechatFields(
window.embeddedservice_bootstrap?.prechatAPI?.setHiddenPrechatFields?.(
prechatFields
);
} catch (error) {
// Silent fail - prechat fields are non-critical.
}
}, { once: true });
};

window.addEventListener(
'onEmbeddedMessagingReady',
onEmbeddedMessagingReadyHandler
);
};

const teardownEmbeddedMessagingReadyHandler = () => {
if (!onEmbeddedMessagingReadyHandler) {
return;
}

window.removeEventListener(
'onEmbeddedMessagingReady',
onEmbeddedMessagingReadyHandler
);
onEmbeddedMessagingReadyHandler = undefined;
};

const invokeEmbeddedMessagingInit = () => {
Expand All @@ -38,7 +69,7 @@ export const loadAgentforceSDK = () => {
return;
}

setupPrechatFields();
setupEmbeddedMessagingReadyHandler();

const script = document.createElement('script');
script.id = 'agentforce-sdk';
Expand All @@ -60,5 +91,6 @@ export const unloadAgentforceSDK = () => {
) {
window.embeddedservice_bootstrap.utilAPI.removeAllComponents();
}
teardownEmbeddedMessagingReadyHandler();
window.AFConsentGranted = false;
};
94 changes: 94 additions & 0 deletions tests/e2e/specs/cmp-settings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@
unloadSDK: () => void;
};
AFConsentGranted?: boolean;
vipAgentforceConsentData?: {
embedding?: {
bootstrapSrc?: string;
};
prechatFields?: Record<string, unknown>;
};
initEmbeddedMessaging?: () => void;
embeddedservice_bootstrap?: {
settings: {
restrictSessionOnMessagingChannel?: boolean;
};
prechatAPI: {
setHiddenPrechatFields: ( fields: Record<string, unknown> ) => void;
};
utilAPI: {
removeAllComponents: () => void;
};
};
}
}

Expand Down Expand Up @@ -86,6 +104,82 @@
} );
} );

test( 'custom consent keeps messaging sessions isolated without prechat fields', async ( { page } ) => {
const cmpSettings = new CmpSettingsPage( page );

await test.step( 'Configure Custom consent', async () => {
await cmpSettings.visit();
await cmpSettings.setConsentType( 'Custom' );
await cmpSettings.save();
} );

await test.step( 'Verify session isolation is applied once per load and listeners do not stack', async () => {
await page.goto( '/' );

const state = await page.evaluate( () => {
const calls = {
sessionIsolation: 0,
hiddenPrechat: 0,
removeAllComponents: 0,
};

const createBootstrap = () => {
return {
settings: {
get restrictSessionOnMessagingChannel() {
return undefined;
},
set restrictSessionOnMessagingChannel( _value ) {
calls.sessionIsolation += 1;
},
},
prechatAPI: {
setHiddenPrechatFields: () => {
calls.hiddenPrechat += 1;
},
},
utilAPI: {
removeAllComponents: () => {
calls.removeAllComponents += 1;
},
},
};
};

window.vipAgentforceConsentData = {
...( window.vipAgentforceConsentData || {} ),
embedding: {
...( window.vipAgentforceConsentData?.embedding || {} ),
bootstrapSrc: 'data:text/javascript,',
},
prechatFields: undefined,
};
window.initEmbeddedMessaging = () => {};
window.embeddedservice_bootstrap = createBootstrap();

window.AgentforceCMP.loadSDK();
window.dispatchEvent( new Event( 'onEmbeddedMessagingReady' ) );
window.AgentforceCMP.unloadSDK();

window.embeddedservice_bootstrap = createBootstrap();
window.AgentforceCMP.loadSDK();
window.dispatchEvent( new Event( 'onEmbeddedMessagingReady' ) );

return {
hasScript: Boolean( document.getElementById( 'agentforce-sdk' ) ),
consent: window.AFConsentGranted === true,
...calls,
};
} );

expect( state.hasScript ).toBe( true );
expect( state.consent ).toBe( true );
expect( state.sessionIsolation ).toBe( 2 );
expect( state.hiddenPrechat ).toBe( 0 );
expect( state.removeAllComponents ).toBe( 1 );
} );
} );

test( 'debug preview auto-injects only for authorized logged-in users', async ( { page, browser, baseURL } ) => {
const cmpSettings = new CmpSettingsPage( page );

Expand Down Expand Up @@ -135,7 +229,7 @@
try {
await anonymousPage.goto( '/wp-login.php?action=logout' );
const logoutLink = anonymousPage.locator( 'a[href*="action=logout"]' ).first();
if ( ( await logoutLink.count() ) > 0 ) {

Check warning on line 232 in tests/e2e/specs/cmp-settings.spec.ts

View workflow job for this annotation

GitHub Actions / Run ESLint on E2E tests

Avoid having conditionals in tests
await logoutLink.click();
}

Expand Down
Loading