summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/web-bundle/resources/test-helpers.js
blob: 5c380c88d87ae359478baeafefe425b5c486f113 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// Helper functions used in web-bundle tests.

function addElementAndWaitForLoad(element) {
  return new Promise((resolve, reject) => {
    element.onload = () => resolve(element);
    element.onerror = () => reject(element);
    document.body.appendChild(element);
  });
}

function addElementAndWaitForError(element) {
  return new Promise((resolve, reject) => {
    element.onload = () => reject(element);
    element.onerror = () => resolve(element);
    document.body.appendChild(element);
  });
}

// Evaluates |code| in |iframe|. The following message event handler must be
// registered on the iframe page:
//   window.addEventListener(
//       'message',
//       (e) => { e.source.postMessage(eval(e.data), e.origin); });
function evalInIframe(iframe, code) {
  const message_promise = new Promise((resolve) => {
      window.addEventListener(
          'message',
          (e) => { resolve(e.data); },
          { once : true });
    });
  iframe.contentWindow.postMessage(code,'*');
  return message_promise;
}

function fetchAndWaitForReject(url) {
  return new Promise((resolve, reject) => {
    fetch(url)
      .then(() => {
        reject();
      })
      .catch(() => {
        resolve();
      });
  });
}

function isValidCrossOriginAttribute(crossorigin) {
  if (crossorigin === undefined)
    return true;
  if ((typeof crossorigin) != 'string')
    return false;
  const lower_crossorigin = crossorigin.toLowerCase();
  return (lower_crossorigin === 'anonymous') ||
         (lower_crossorigin  === 'use-credentials');
}

function addScriptAndWaitForError(url) {
  return new Promise((resolve, reject) => {
    const script = document.createElement("script");
    script.src = url;
    script.onload = reject;
    script.onerror = resolve;
    document.body.appendChild(script);
  });
}

function addScriptAndWaitForExecution(url) {
  return new Promise((resolve, reject) => {
    window.scriptLoaded = (val) => {
      window.scriptLoaded = undefined;
      resolve(val);
    };
    const script = document.createElement("script");
    script.src = url;
    script.onerror = reject;
    document.body.appendChild(script);
  });
}

function createWebBundleElement(url, resources, options) {
  const script = document.createElement("script");
  script.type = "webbundle";
  const json_rule  = {"source": url, "resources": resources};
  if (options && options.scopes) {
    json_rule.scopes = options.scopes;
  }
  if (options && options.credentials) {
    json_rule.credentials = options.credentials;
  }
  script.textContent = JSON.stringify(json_rule);
  return script;
}

function addWebBundleElementAndWaitForLoad(url, resources, options) {
  const element = createWebBundleElement(url, resources, options);
  return addElementAndWaitForLoad(element);
}

function addWebBundleElementAndWaitForError(url, resources, options) {
  const element = createWebBundleElement(url, resources, options);
  return addElementAndWaitForError(element);
}

function changeWebBundleUrlInPlace(element, new_url) {
  if (window.TEST_WEB_BUNDLE_ELEMENT_TYPE != 'link') {
    throw new Error(
        'Changing the URL of web bundle is not supported for : ' +
        window.TEST_WEB_BUNDLE_ELEMENT_TYPE);
  }
  element.href= new_url;
}

function changeWebBundleScopesInPlace(element, scopes) {
  if (window.TEST_WEB_BUNDLE_ELEMENT_TYPE != 'link') {
    throw new Error(
        'Changing the scopes of web bundle is not supported for : ' +
        window.TEST_WEB_BUNDLE_ELEMENT_TYPE);
  }
  element.scopes = '';
  for (const scope of scopes) {
    element.scopes.add(scope);
  }
}

function changeWebBundleResourcesInPlace(element, resources) {
  if (window.TEST_WEB_BUNDLE_ELEMENT_TYPE != 'link') {
    throw new Error(
        'Changing the resources of web bundle is not supported for : ' +
        window.TEST_WEB_BUNDLE_ELEMENT_TYPE);
  }
  element.resources = '';
  for (const url of resources) {
    element.resources.add(url);
  }
}

// This function creates a new WebBundle element that has a rule
// constructed in accordance with a JSON object |new_rule|:
// 1. Copy over WebBundle rules from an existing element that are
// not present in |new_rule|, in case of <link> API it is all
// relevant attributes: href, resources, scopes and crossOrigin;
// in case of <script> API, it is: source, resources, scopes and
// credentials.
// 2. Then create a new WebBundle element from |new_rule| (that now
// has full information required after 1.) and return it.
function createNewWebBundleElementWithUpdatedRule(element, new_rule) {
  if (window.TEST_WEB_BUNDLE_ELEMENT_TYPE == 'link') {
    if (element.resources && !new_rule.resources)
      new_rule.resources = Array.from(element.resources);
    if (element.scopes && !new_rule.scopes)
      new_rule.scopes = Array.from(element.scopes);
    if (element.crossOrigin && !new_rule.crossOrigin)
      new_rule.crossOrigin = element.crossOrigin;
    if (!new_rule.url)
      new_rule.url = element.href;
  } else {
    const rule = JSON.parse(element.textContent);
    if (rule.resources && !new_rule.resources)
      new_rule.resources = rule.resources;
    if (rule.scopes && !new_rule.scopes)
      new_rule.scopes = rule.scopes;
    if (rule.credentials && !new_rule.credentials)
      new_rule.credentials = rule.credentials;
    if (!new_rule.url)
      new_rule.url = rule.source;
  }

  return createWebBundleElement(new_rule.url, new_rule.resources, new_rule);
}