-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathindex.js
More file actions
128 lines (98 loc) · 3.29 KB
/
index.js
File metadata and controls
128 lines (98 loc) · 3.29 KB
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
import { fetch } from 'whatwg-fetch';
import { setupContext, teardownContext } from '@ember/test-helpers';
import { mockServer } from './-private/mock-server';
import param from 'jquery-param';
import * as Comlink from 'comlink';
export function setup(hooks) {
hooks.beforeEach(async function() {
await mockServer.cleanUp();
return setupContext(this);
});
hooks.afterEach(async function() {
await mockServer.cleanUp();
return teardownContext(this);
});
}
export async function fastboot(url, { headers = {} }) {
let response = await fetchFromEmberCli(url, headers);
let result = await response.json();
let body = result.err ?
formatError(result.err) :
extractBody(result.html);
result.htmlDocument = parseHtml(result.html)
result.body = body;
return result;
}
export async function visit(url, options = {}) {
let result = await fastboot(url, { headers: options.headers || {} });
document.querySelector('#ember-testing').innerHTML = result.body;
return result;
}
export { mockServer };
export const nock = Comlink.wrapChain({
listeners: [],
async postMessage(message) {
let response = await fetch('/__nock-proxy', {
method: 'post',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(message),
});
let result = await response.json();
for (let listener of this.listeners) {
listener({ data: result });
}
},
addEventListener(type, listener) {
this.listeners.push(listener);
},
removeEventListener(type, listener) {
let index = this.listeners.indexOf(listener);
this.listeners.splice(index, 1);
},
});
// private
let fetchFromEmberCli = async function(url, headers) {
let endpoint = `/__fastboot-testing?${param({url, headers})}`;
let response;
let error;
try {
response = await fetch(endpoint);
} catch (e) {
if (e.message && e.message.match(/^Mirage:/)) {
error = `It looks like Mirage is intercepting ember-cli-fastboot-testing's attempt to render ${url}. Please disable Mirage when running FastBoot tests.`;
} else {
error = `We were unable to render ${url}. Is your test suite blocking or intercepting HTTP requests? Error: ${e.message ? e.message : e}.`
}
}
if (response && response.headers && response.headers.get && response.headers.get('x-fastboot-testing') !== 'true') {
error = `We were unable to render ${url}. Is your test suite blocking or intercepting HTTP requests?`;
}
if (error) {
error = `Ember CLI FastBoot Testing: ${error}`;
// eslint-disable-next-line no-console
console.error(error);
throw new Error(error);
}
return response;
};
let parseHtml = function(str) {
let parser = new DOMParser();
return parser.parseFromString(str, "text/html");
}
let extractBody = function(html) {
let start = '<script type="x/boundary" id="fastboot-body-start"></script>';
let end = '<script type="x/boundary" id="fastboot-body-end"></script>';
let startPosition = html.indexOf(start);
let endPosition = html.indexOf(end);
if (!startPosition || !endPosition) {
throw "Could not find fastboot boundary";
}
let startAt = startPosition + start.length;
let endAt = endPosition - startAt;
return html.substr(startAt, endAt);
}
let formatError = function(err) {
return `<pre>${err.stack}</pre>`;
};