1 | import { View } from 'aurelia-templating';
|
2 | import { waitFor } from './wait';
|
3 | export class StageComponent {
|
4 | static withResources(resources = []) {
|
5 | return new ComponentTester().withResources(resources);
|
6 | }
|
7 | }
|
8 | export class ComponentTester {
|
9 | constructor() {
|
10 | this.resources = [];
|
11 | }
|
12 | configure(aurelia) {
|
13 | return aurelia.use.standardConfiguration();
|
14 | }
|
15 | bootstrap(configure) {
|
16 | this.configure = configure;
|
17 | }
|
18 | withResources(resources) {
|
19 | this.resources = resources;
|
20 | return this;
|
21 | }
|
22 | inView(html) {
|
23 | this.html = html;
|
24 | return this;
|
25 | }
|
26 | boundTo(bindingContext) {
|
27 | this.bindingContext = bindingContext;
|
28 | return this;
|
29 | }
|
30 | manuallyHandleLifecycle() {
|
31 | this._prepareLifecycle();
|
32 | return this;
|
33 | }
|
34 | create(bootstrap) {
|
35 | return bootstrap((aurelia) => {
|
36 | return Promise.resolve(this.configure(aurelia)).then(() => {
|
37 | if (this.resources) {
|
38 | aurelia.use.globalResources(this.resources);
|
39 | }
|
40 | return aurelia.start().then(() => {
|
41 | this.host = document.createElement('div');
|
42 | this.host.innerHTML = this.html;
|
43 | document.body.appendChild(this.host);
|
44 | return aurelia.enhance(this.bindingContext, this.host).then(() => {
|
45 | this.rootView = aurelia.root;
|
46 | this.element = this.host.firstElementChild;
|
47 | if (aurelia.root.controllers.length) {
|
48 | this.viewModel = aurelia.root.controllers[0].viewModel;
|
49 | }
|
50 | return new Promise(resolve => setTimeout(() => resolve(), 0));
|
51 | });
|
52 | });
|
53 | });
|
54 | });
|
55 | }
|
56 | dispose() {
|
57 | if (this.host === undefined || this.rootView === undefined) {
|
58 | throw new Error('Cannot call ComponentTester.dispose() before ComponentTester.create()');
|
59 | }
|
60 | this.rootView.detached();
|
61 | this.rootView.unbind();
|
62 | return this.host.parentNode.removeChild(this.host);
|
63 | }
|
64 | _prepareLifecycle() {
|
65 |
|
66 | const bindPrototype = View.prototype.bind;
|
67 |
|
68 | View.prototype.bind = () => { };
|
69 | this.bind = bindingContext => new Promise(resolve => {
|
70 | View.prototype.bind = bindPrototype;
|
71 | if (bindingContext !== undefined) {
|
72 | this.bindingContext = bindingContext;
|
73 | }
|
74 | this.rootView.bind(this.bindingContext);
|
75 | setTimeout(() => resolve(), 0);
|
76 | });
|
77 |
|
78 | const attachedPrototype = View.prototype.attached;
|
79 |
|
80 | View.prototype.attached = () => { };
|
81 | this.attached = () => new Promise(resolve => {
|
82 | View.prototype.attached = attachedPrototype;
|
83 | this.rootView.attached();
|
84 | setTimeout(() => resolve(), 0);
|
85 | });
|
86 |
|
87 | this.detached = () => new Promise(resolve => {
|
88 | this.rootView.detached();
|
89 | setTimeout(() => resolve(), 0);
|
90 | });
|
91 |
|
92 | this.unbind = () => new Promise(resolve => {
|
93 | this.rootView.unbind();
|
94 | setTimeout(() => resolve(), 0);
|
95 | });
|
96 | }
|
97 | waitForElement(selector, options) {
|
98 | return waitFor(() => this.element.querySelector(selector), options);
|
99 | }
|
100 | waitForElements(selector, options) {
|
101 | return waitFor(() => this.element.querySelectorAll(selector), options);
|
102 | }
|
103 | }
|