How I “solved” it:
Guides:
Hi,
The problem I am having is during testing, au test
dev-server, au run
, works fine
CodeSandBox
As suggested by @Sayan751
I don’t know how to get the .spec files working in CodeSandBox
All files works in local env (my computer / aurelia-cli)
I am stuck trying to test a <compose>
element
ref
-ed element within compose
<template>
tag is undefined when console.log
-ed (see Spec code below)
I am unsure how to call the activate(model)
method when testing (see Spec code below)
Thanks for looking at this.
I’m using:
.js (babel)
karma/jasmine
alameda
aurelia-cli: 1.3.0
aurelia-testing: 1.0.0
Parent (HTML):
<template>
<compose view-model="./compose-elem" model.bind="model"></compose>
</template>
ViewModel:
import { inject, observable } from "aurelia-framework"
@inject(Element)
export class ComposeElem {
@observable
stuff
constructor (Element) {
this.element = Element
}
activate (model) {
this.stuff = model
}
attached () {
console.log("dev-server compose-elem ref check", this.divReference)
}
}
View:
<template>
<div ref="divReference">
Compose Element
<br />
@observable stuff = ${ stuff }
</div>
</template>
Spec:
import { bootstrap } from "aurelia-bootstrapper"
import { StageComponent } from "aurelia-testing"
fdescribe("Compose-Elem", () => {
let component
beforeEach(async (done) => {
component = StageComponent.withResources("./compose-elem")
.inView(
`
<compose
view-model="./compose-elem"
model.bind="model">
</compose>
`,
)
.boundTo({
model: "data",
})
done()
})
afterEach(async (done) => {
component.dispose()
done()
})
describe("Test Group", async () => {
it("test unit", async (done) => {
component
.create(bootstrap)
// .then(() => component.activate()) // Failed: component.activate is not a function
// .then(() => component.viewModel.activate()) // Failed: component.viewModel.activate is not a function
.then(async () => {
const viewModel = component.viewModel
console.log("test-server compose-elem ref check", viewModel.divReference) // undefined
console.log("test-server compose-elem activate() check", viewModel.stuff) // undefined (cannot call activate())
done()
})
.catch((e) => {
fail(e)
done()
})
})
})
})
Edits:
Change confusing element name
Add more details about the problem
Edit/Add code
Edit/Add CodeSandBox
Add guide links from others’ post
Add my “solution”
1 Like
Hi @LetsZiggy , is it possible for you to share a reproducable example? You can also create a codesandbox if you want. Here is a starter app: https://codesandbox.io/s/aurelia-typescript-sandbox-zw9zjy0683 .
On a different note, I am curious about if you are trying to create your own compose
element or it is just a regular custom element with the same name.
1 Like
Hi @Sayan751 ,
CodeSandBox link
I’ve updated my original post to further clarify the problem. Sorry for the confusing names.
All code in dev-server, au run
, works
Only in test-server, au test
, I have problems
I’m using <compose>
in the parent html; the example uses app.html
I’m cannot get the test running on CodeSandBox but it runs locally, au test
, for what it’s worth
Thanks again for the help
Edits:
Add details
Edit CodeSandBox link
1 Like
I have arranged some example in this temp repo https://github.com/Sayan751/au-compose-el-unit-test.In short, when testing the a "compose"d custom element, it is better to handle the lifecycle manually.
import { bootstrap } from "aurelia-bootstrapper"
import { StageComponent, ComponentTester } from "aurelia-testing"
import { PLATFORM } from 'aurelia-pal';
import { ComposeElem } from "compose-elem";
describe("Compose-Elem", () => {
let component: ComponentTester<ComposeElem>;
beforeEach(() => {
component = StageComponent
.withResources(PLATFORM.moduleName("compose-elem"))
.inView(`<compose-elem></compose-elem>`)
.manuallyHandleLifecycle();
});
afterEach(() => {
component.dispose();
});
it("test unit", async () => {
This file has been truncated. show original
I would suggest to fork it, so that I can delete it.
2 Likes
@Sayan751 ,
Thanks. I’ve forked the repo.
I’ll update this post after I’ve written the test.
Didn’t work for me even with au new
More details below
Thanks again.
Edits:
Minor post edit
Add more details
1 Like
@Sayan751 ,
I cannot get the test to work even with au new
Below are the terminal outputs for au test --watch
compose-elem.spec.js => Default jasmine.DEFAULT_TIMEOUT_INTERVAL
...
Starting 'karma'...
22 04 2020 16:47:37.100:WARN [karma]: No captured browser, open http://localhost:9876/
22 04 2020 16:47:37.133:INFO [karma-server]: Karma v4.4.1 server started at http://0.0.0.0:9876/
22 04 2020 16:47:37.134:INFO [launcher]: Launching browsers ChromeHeadless with concurrency unlimited
22 04 2020 16:47:37.144:INFO [launcher]: Starting browser Chrome
22 04 2020 16:47:37.655:INFO [HeadlessChrome 81.0.4044 (Linux 0.0.0)]: Connected on socket bekprfv7SpeUetCQAAAA with id 7053135
HeadlessChrome 81.0.4044 (Linux 0.0.0) Compose-Elem Test Group test unit FAILED
Error: Timeout - Async function did not complete within 5000ms (set by jasmine.DEFAULT_TIMEOUT_INTERVAL)
at <Jasmine>
HeadlessChrome 81.0.4044 (Linux 0.0.0): Executed 1 of 2 (1 FAILED) (skipped 1) (5.032 secs / 5.017 secs)
TOTAL: 1 FAILED, 0 SUCCESS
compose-elem.spec.js => it("test unit", async () => { ... }, 10000)
...
Starting 'karma'...
22 04 2020 16:51:39.042:WARN [karma]: No captured browser, open http://localhost:9876/
22 04 2020 16:51:39.071:INFO [karma-server]: Karma v4.4.1 server started at http://0.0.0.0:9876/
22 04 2020 16:51:39.072:INFO [launcher]: Launching browsers ChromeHeadless with concurrency unlimited
22 04 2020 16:51:39.091:INFO [launcher]: Starting browser Chrome
22 04 2020 16:51:39.593:INFO [HeadlessChrome 81.0.4044 (Linux 0.0.0)]: Connected on socket 7gOTejrCWW4t8ohoAAAA with id 4836018
HeadlessChrome 81.0.4044 (Linux 0.0.0) Compose-Elem Test Group test unit FAILED
Error: Timeout - Async function did not complete within 10000ms (custom timeout)
at <Jasmine>
HeadlessChrome 81.0.4044 (Linux 0.0.0): Executed 1 of 2 (1 FAILED) (skipped 1) (10.035 secs / 10.017 secs)
TOTAL: 1 FAILED, 0 SUCCESS
custom-elem.spec.js for comparison (with .manuallyHandleLifecycle())
Starting 'karma'...
22 04 2020 18:13:09.203:WARN [karma]: No captured browser, open http://localhost:9876/
22 04 2020 18:13:09.227:INFO [karma-server]: Karma v4.4.1 server started at http://0.0.0.0:9876/
22 04 2020 18:13:09.228:INFO [launcher]: Launching browsers ChromeHeadless with concurrency unlimited
22 04 2020 18:13:09.237:INFO [launcher]: Starting browser Chrome
22 04 2020 18:13:09.717:INFO [HeadlessChrome 81.0.4044 (Linux 0.0.0)]: Connected on socket bijYquQyX4vYXozJAAAA with id 57667270
LOG: 'dev-server compose-elem stuffChanged', 'new data', 'old data'
HeadlessChrome 81.0.4044 (Linux 0.0.0) Compose-Elem Test Group test unit FAILED
Error: Timeout - Async function did not complete within 10000ms (custom timeout)
at <Jasmine>
LOG: 'dev-server custom-elem stuffChanged', 'new data', 'old data'
LOG: 'test-server custom-elem ref check', <div ref="divReference" class="au-target" au-target-id="4">Custom Element<br>@bindable stuff = new data </div>
LOG: 'test-server custom-elem @bindable check', 'new data'
HeadlessChrome 81.0.4044 (Linux 0.0.0): Executed 2 of 3 (1 FAILED) (skipped 1) (10.064 secs / 10.043 secs)
TOTAL: 1 FAILED, 1 SUCCESS
Edits:
Minor post edit
Update git repo
1 Like
For a timeout failure like this, easiest way to debug is to return after each await until you hit the line that’s hanging everything.
1 Like
@bigopon ,
ok thanks. will try
Found the problem: component.viewModel.activate("data")
I don’t know the way forward from this … any advice?
Thanks
Test:
import { bootstrap } from "aurelia-bootstrapper"
import { StageComponent } from "aurelia-testing"
fdescribe("Compose-Elem", () => {
let component
beforeEach(async (done) => {
/*
component = StageComponent
.withResources("elements/compose-elem")
.inView(`
<compose>
</compose>
`)
.manuallyHandleLifecycle()
*/
/**/
component = StageComponent
.withResources("elements/compose-elem")
.inView(`
<compose
view-model="elements/compose-elem"
model.bind="model">
</compose>
`)
.boundTo({ model: "new data" })
.manuallyHandleLifecycle()
/**/
done()
})
afterEach(async (done) => {
component
.dispose()
done()
})
describe("Test Group", async () => {
it("test unit", async (done) => {
await component.create(bootstrap)
await component.bind()
component.viewModel.activate("new data")
done()
/*
- Error on activate()
- Success on bind() and create()
*/
// await component.attached()
// const element = component.element
// expect(element.querySelector("div").textContent)
// .toContain("stuff = new data")
// const viewModel = component.viewModel
// console.log(
// "test-server compose-elem ref check",
// viewModel.divReference,
// )
// console.log(
// "test-server compose-elem activate() check",
// viewModel.stuff,
// )
// await component.detached()
// await component.unbind()
// done()
})
})
})
Edits:
Update post after trying @bigopon 's advice
@LetsZiggy As you need to test your component, you need to change your inView
template. Also as the “model” for the component will be bound via the component.viewModel.activate
method, you can also drop the .boundTo
. In summary the changes look as follows (from your compose-elem.spec.js
):
component = StageComponent
.withResources("elements/compose-elem")
- .inView(`
- <compose
- view-model="elements/compose-elem"
- model.bind="model">
- </compose>
- `)
- .boundTo({ model: "new data" })
+ .inView(`<compose-elem></compose-elem>`)
1 Like
it’s the same either way, i.e. as code below or as code in previous post
anyway i’ll chalk it up to either my computer or my au setup (i’ve not tried with webpack/requirejs or jest or both)
i’ll just use regular custom-elements and au.enhance if i need it to be dynamic
my bad … I misread your answer . You correctly showed to test as custom-element.
thanks for taking your time looking into this @Sayan751 & @bigopon
Ignore the code below…
...
component = StageComponent
.withResources("elements/compose-elem")
.inView(`<compose></compose>`)
.manuallyHandleLifecycle()
...
Edits:
Add more details
Add where I went wrong…please see post
my bad … I misread the answer given . You correctly showed to test as custom-element.
I think I’ve figured out how to test a <compose>
element. Test <compose>
as custom element; i.e. .inView('<compose-elem></compose-elem>')
github repo
Thanks @Sayan751 and @bigopon for helping me on this
import { bootstrap } from "aurelia-bootstrapper"
import { StageComponent } from "aurelia-testing"
const sleep = (ms = 0) => new Promise((resolve) => setTimeout(resolve, ms))
describe("Compose-Elem", () => {
let component
beforeEach(async (done) => {
/*
component = StageComponent
.withResources("compose-elem")
.inView(`<compose></compose>`)
.manuallyHandleLifecycle()
*/
component = StageComponent
.withResources("compose-elem")
.inView(`<compose-elem></compose-elem>`)
.manuallyHandleLifecycle()
done()
})
afterEach(async (done) => {
component
.dispose()
done()
})
describe("Test Group", async () => {
it("test unit", async (done) => {
await component.create(bootstrap)
await component.bind(undefined)
component.viewModel.activate("new data")
await component.attached()
const viewModel = component.viewModel
const element = component.element
expect(element.querySelector("div").textContent)
.toContain("stuff = new data")
viewModel.stuff = "extra new data"
await sleep(200)
expect(element.querySelector("div").textContent)
.toContain("stuff = extra new data")
await component.detached()
await component.unbind()
done()
})
})
})
Edits:
Update code in post
Add where I went wrong…please see post
1 Like