Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POC for basic web platform test integration #2585

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft

Conversation

jasnell
Copy link
Member

@jasnell jasnell commented Aug 22, 2024

This is just a proof of concept to start working through what is necessary to integrate web platform tests into wd-tests.

There are some limitations to this approach...

  1. All module imports are evaluated outside of an IoContext, even if they are dynamic imports. This means that no test can schedule any actual i/o. Any test that depends on setTimeout, for instance, won't work with this pattern. This also means that none of the fetch tests would work under this pattern (EventSource, timers, Web Sockets, etc, all wouldn't be possible with this approach)
  2. The test harness messes with the global scope. Ideally we'd be running these things in something like a ShadowRealm ... otherwise there's always a possibility of the harness conflicting with the global scope, tho that is unlikely in practice

allow_empty = True,
),
visibility = ["//visibility:public"],
)
Copy link
Member Author

Choose a reason for hiding this comment

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

We would need to export filegroups for each of the web platform test groups we want... we don't need to export filegroups for everything since most of the wpts will never be relevant

],
) for f in glob(
["**/*.wd-test"],
)]
Copy link
Member Author

Choose a reason for hiding this comment

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

Most likely should list each individually rather than using the glob here so that we can selectively import the appropriate wpt filegroups.

Comment on lines 5 to 29
globalThis.fetch = async(url) => {
const { default: data } = await import(url);
return {
async json() { return data; },
};
};

globalThis.promise_test = (callback) => {
callback();
};

globalThis.assert_equals = (a, b, c) => {
strictEqual(a,b,c);
};

globalThis.test = (callback, message) => {
try {
callback();
} catch (err) {
const aerr = new AggregateError([err], message);
globalThis.errors.push(aerr);
}
}

globalThis.errors = [];
Copy link
Member Author

Choose a reason for hiding this comment

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

In order to be able to run the tests we need to define the test harness methods along with a way of collecting the results. This is a bit wonky here.


export const test = {
async test(_, env) {
const foo = await import('url-origin.any.js');
Copy link
Member Author

Choose a reason for hiding this comment

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

The tests end up running when the module is evaluated. We have to set the global test harness methods before the dynamic import, then check the globalThis.errors when we're done. The globalThis.errors is only specific to this test file, it is not actually part of the WPT test harness. We have to do this because the tests themselves may not actually propagate the error (in the case of url-origin.any.js we end up with a swallowed rejected promise) if we don't have this.

Copy link
Member

Choose a reason for hiding this comment

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

We also need a way to ignore certain errors. Possibly from a module_name.json file with a JSON schema that conforms to our needs

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I'm thinking that can be a separate json module that is imported and used by the harness.

@jasnell jasnell force-pushed the jsnell/wip-wpt branch 2 times, most recently from 7c954b5 to e5803d7 Compare August 22, 2024 19:07
load("//:build/wd_test.bzl", "wd_test")
load("//src/workerd/api/wpt:generate-tests.bzl", "gen_wpt_tests")

gen_wpt_tests(glob(["**/*.js"]))
Copy link
Member Author

Choose a reason for hiding this comment

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

Some documentation comments around this would be helpful.

async test() {
harness.prepare();
await import('url-constructor.any.js');
harness.validate();
Copy link
Member Author

Choose a reason for hiding this comment

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

Side note: Our workerd tests could benefit from having a before() { ... } and after() { ... } mechanism.

Copy link
Member Author

@jasnell jasnell Sep 10, 2024

Choose a reason for hiding this comment

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

I suppose we could have a pattern like...

import * as harness from 'harness';

export const urlConstructor = {
  test: harness.test('url-constructor.any.js');
};

// or

export const urlConstructor = harness.test('url-constructor.any.js');

Where the harness.test(...) handles any of the necessary boilerplate for the most typical cases?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah sounds like a good idea

@@ -0,0 +1,41 @@
import { strictEqual } from 'node:assert';
Copy link
Member Author

Choose a reason for hiding this comment

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

Side note... let's try not to forget adding the copyright headers to these (speaking to myself here mostly)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants