Automatic update from web-platform-tests [WebMCP] Fix WPTs for WebMCP after getTools() change. - Updates all cross-origin WebMCP Web Platform Tests (WPT) to utilize the new API with explicit `fromOrigins` parameters, ensuring they now pass cleanly. - Removes the temporary failure expectations for these WPT tests from TestExpectations. Bug: 485810761 Change-Id: Ia278140565a3c2f1aa6896685a3fcba3ef9500f0 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7913488 Reviewed-by: Dominic Farolino <dom@chromium.org> Commit-Queue: Dominic Farolino <dom@chromium.org> Cr-Commit-Position: refs/heads/main@{#1644383} -- wpt-commits: 8894a59b3a729aebd3427ea8572a0f14b37792df wpt-pr: 60514
104 lines
4.1 KiB
HTML
104 lines
4.1 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>WebMCP Complex Origin-Based Exposure</title>
|
|
<meta name="timeout" content="long">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/common/get-host-info.sub.js"></script>
|
|
<script src="resources/helpers.js"></script>
|
|
</head>
|
|
<body>
|
|
<script>
|
|
const host_info = get_host_info();
|
|
|
|
promise_test(async t => {
|
|
const origin_a = host_info.HTTPS_ORIGIN;
|
|
const origin_b = host_info.HTTPS_REMOTE_ORIGIN;
|
|
const origin_c = host_info.HTTPS_OTHER_NOTSAMESITE_ORIGIN;
|
|
|
|
// Setup iframes with multiple origins: Parent=A, Child1=B, Child2=C.
|
|
const iframe_b = document.createElement('iframe');
|
|
iframe_b.src = origin_b + '/webmcp/imperative/resources/iframe-register-tool.html';
|
|
iframe_b.allow = 'tools *';
|
|
|
|
const iframe_c = document.createElement('iframe');
|
|
iframe_c.src = origin_c + '/webmcp/imperative/resources/iframe-register-tool.html';
|
|
iframe_c.allow = 'tools *';
|
|
|
|
const load_promise_b = new Promise(resolve => iframe_b.onload = resolve);
|
|
const load_promise_c = new Promise(resolve => iframe_c.onload = resolve);
|
|
|
|
document.body.appendChild(iframe_b);
|
|
t.add_cleanup(() => iframe_b.remove());
|
|
document.body.appendChild(iframe_c);
|
|
t.add_cleanup(() => iframe_c.remove());
|
|
|
|
await Promise.all([load_promise_b, load_promise_c]);
|
|
|
|
// Meat of the test begins:
|
|
|
|
// Frame B exposes tool to Frame C only. Frame C should observe `toolchange` event.
|
|
iframe_c.contentWindow.postMessage('listenForToolchange', '*');
|
|
await waitForIframeMessage('toolchange_listening_ack');
|
|
|
|
const toolchange_promise = waitForIframeMessage('toolchange_result');
|
|
|
|
iframe_b.contentWindow.postMessage({
|
|
action: 'register',
|
|
tool: {
|
|
name: 'tool_b_to_c',
|
|
description: 'Tool B exposed to C',
|
|
inputSchema: { type: 'object', properties: { query: { type: 'string' } } }
|
|
},
|
|
options: { exposedTo: [origin_c] }
|
|
}, '*');
|
|
|
|
const toolchange_result = await toolchange_promise;
|
|
assert_equals(toolchange_result.result, 'fired', 'Frame C received toolchange event');
|
|
|
|
// Parent does not see the tool.
|
|
let tools = await document.modelContext.getTools();
|
|
assert_array_equals(tools, [], "Parent sees no tools");
|
|
|
|
// Frame C should see the tool.
|
|
iframe_c.contentWindow.postMessage(
|
|
{action: 'getTools', options: {fromOrigins: [origin_b]}}, '*');
|
|
let response = await waitForIframeMessage('getToolsResponse');
|
|
const [tool] = response.tools;
|
|
assert_true(toolsAreEqual(tool, {
|
|
name: 'tool_b_to_c',
|
|
description: 'Tool B exposed to C',
|
|
inputSchema: JSON.stringify({ type: 'object', properties: { query: { type: 'string' } } }),
|
|
origin: origin_b
|
|
}), 'Tool details should match');
|
|
|
|
// Now, we make B unregister the tool, and assert that:
|
|
// 1. `toolchange` fires in C.
|
|
// 3. Frame C can no longer see the tool in `getTools()`.
|
|
iframe_c.contentWindow.postMessage('listenForToolchange', '*');
|
|
await waitForIframeMessage('toolchange_listening_ack');
|
|
const child_unreg_promise = waitForIframeMessage('toolchange_result');
|
|
|
|
// 2. `toolchange` does not fire in the parent frame.
|
|
let unreg_fired = false;
|
|
const unreg_listener = () => { unreg_fired = true; };
|
|
document.modelContext.addEventListener('toolchange', unreg_listener);
|
|
const parent_timeout_promise = new Promise(resolve => t.step_timeout(resolve, 4000));
|
|
|
|
iframe_b.contentWindow.postMessage({ action: 'unregister', name: 'tool_b_to_c' }, '*');
|
|
const [child_response] = await Promise.all([child_unreg_promise, parent_timeout_promise]);
|
|
|
|
document.modelContext.removeEventListener('toolchange', unreg_listener);
|
|
assert_false(unreg_fired, 'Parent should not receive toolchange event on unregistration');
|
|
assert_equals(child_response.result, 'fired', 'Frame C should receive toolchange event on unregistration');
|
|
|
|
iframe_c.contentWindow.postMessage(
|
|
{action: 'getTools', options: {fromOrigins: [origin_b]}}, '*');
|
|
response = await waitForIframeMessage('getToolsResponse');
|
|
assert_array_equals(response.tools, [], "Frame C no longer sees B's tool");
|
|
}, 'Multi-origin setup with mixed exposure lists');
|
|
</script>
|
|
</body>
|
|
</html>
|