<!DOCTYPE html>
<html>
<body>
<script src="../resources/js-test-pre.js"></script>
<script>

description('This tests the order by which tasks are scheduled across documents that are not similar origins.');

if (!window.internals)
    testFailed('This test relies on window.internals');
else {
    jsTestIsAsync = true;
    window.onload = startTest;
}

logs = [];
crossOriginLogs = [];

async function startTest()
{
    window.frame1 = document.createElement('iframe');
    document.body.appendChild(frame1);

    window.frame2 = document.createElement('iframe');
    frame2.name = 'frame2';
    frame2.src = 'http://localhost:8000/eventloop/resources/eventloop-helper.html';
    document.body.appendChild(frame2);

    window.frame3 = document.createElement('iframe');
    frame3.src = 'resources/eventloop-helper.html';
    document.body.appendChild(frame3);

    window.frame4 = document.createElement('iframe');
    frame4.name = 'frame4';
    frame4.src = 'http://localhost:8000/eventloop/resources/eventloop-helper.html';

    await waitForLoad(frame3);
    frame3.contentDocument.body.appendChild(frame4);

    await waitForLoad(frame2);
    await waitForLoad(frame4);

    frame3.contentWindow.internals.queueTask("DOMManipulation", () => logs.push('1'));
    frame3.contentWindow.internals.queueTask("DOMManipulation", () => logs.push('2'));
    internals.queueTask("DOMManipulation", () => logs.push('3'));
    frame1.contentWindow.internals.queueTask("DOMManipulation", () => logs.push('4'));
    internals.queueTask("DOMManipulation", () => logs.push('5'));

    frame2.contentWindow.postMessage({
        type: 'run',
        order: ['frame2', 'frame2', 'self'],
        startingNumber: 10,
    }, '*');

    await new Promise((resolve) => { window.resolveCrossOriginLogs = resolve; });

    setTimeout(() => {
        shouldBeEqualToString('logs.join(", ")', '1, 2, 3, 4, 5');
        shouldBeEqualToString('crossOriginLogs.join(", ")', '10, 11, 12');
        shouldBeTrue('internals.hasSameEventLoopAs(frame1.contentWindow)');
        shouldBeFalse('internals.hasSameEventLoopAs(frame2.contentWindow)');
        shouldBeTrue('internals.hasSameEventLoopAs(frame3.contentWindow)');
        shouldBeFalse('internals.hasSameEventLoopAs(frame4.contentWindow)');
        finishJSTest();
    }, 100);
}

const loadedFrames = new Map;
onmessage = (event) => {
    if (event.data.type == 'load') {
        const resolve = loadedFrames.get(event.source);
        if (resolve)
            resolve();
        else
            loadedFrames.set(event.source, null);
    } else if (event.data.type == 'logs') {
        crossOriginLogs = event.data.logs;
        resolveCrossOriginLogs();
    }
}

function waitForLoad(frame)
{
    if (loadedFrames.has(frame.contentWindow))
        return Promise.resolve();
    return new Promise((resolve) => loadedFrames.set(frame.contentWindow, resolve));
}

successfullyParsed = true;

</script>
<script src="../resources/js-test-post.js"></script>
</body>
</html>
