Skip to content

Commit

Permalink
fix(component-tester): fix bug where @containerless components wouldn…
Browse files Browse the repository at this point in the history
…'t be initialized properly, this breaks the ability to manually call detached() lifecycle methods on the component for the time-being however (#12)

Fixes #11
  • Loading branch information
silbinarywolf authored Feb 1, 2019
1 parent ab24fe9 commit 7a8b69e
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 67 deletions.
17 changes: 17 additions & 0 deletions cypress/integration/unit/containerless-div.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { PLATFORM } from 'aurelia-framework';
import { bootstrap } from 'aurelia-bootstrapper';
import { StageComponent } from 'cypress-aurelia-unit-test';

import { ContainerlessDiv } from '~/containerless-div/containerless-div';

describe('ContainerlessDiv', () => {
it('Test that we properly render a containerless component and calls attached() once', () => {
const component = StageComponent
.withResources<ContainerlessDiv>(PLATFORM.moduleName('containerless-div/containerless-div'))
.inView(`<containerless-div></containerless-div>`);
component.create(bootstrap);
cy.get('containerless-div').should('not.exist');
const AttachedMethodCalledCount = '1';
cy.get(`div`).contains(AttachedMethodCalledCount);
});
});
74 changes: 7 additions & 67 deletions lib/component-tester.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
/// <reference types="cypress" />

import 'reflect-metadata';
import { Aurelia, Container, FrameworkConfiguration, ViewCompiler, ViewResources } from 'aurelia-framework';
import { Aurelia, FrameworkConfiguration } from 'aurelia-framework';
import { DOM } from 'aurelia-pal';
import { View } from 'aurelia-templating';

// NOTE(Jake): 2019-01-07
// Used by aurelia-testing. Keeping incase we want to reintroduce.
// interface AureliaWithRoot extends Aurelia {
// root: ViewWithControllers;
// }

interface ViewWithControllers extends View {
controllers: Array<{ viewModel: any }>;
}
// interface ViewWithControllers extends View {
// controllers: Array<{ viewModel: any }>;
// }

// track the patches being used
let patches = newPatches();
Expand All @@ -24,19 +22,6 @@ const aureliaDialogWarningMessage = 'aurelia-dialog causes Cypress to crash. Rem
// and "losing" styles when the next test starts
const stylesCache: Map<string, NodeListOf<Element>> = new Map<string, NodeListOf<Element>>();

// track components that were attached so they can be detached before
// each build
const componentsAttached: any[] = [];

function disposeComponents() {
for (const component of componentsAttached) {
if (component.detached) {
component.detached();
}
}
componentsAttached.length = 0;
}

// NOTE: Jake: 2018-12-18
// Taken from: https://github.com/bahmutov/cypress-react-unit-test/blob/master/lib/index.js
function copyStyles(componentName: string): void {
Expand Down Expand Up @@ -89,10 +74,6 @@ export class _ {

export class StageComponent {
public static withResources<T = any>(resources: string | string[] = []): ComponentTester<T> {
// NOTE: Jake: 2018-12-19
// Any components we tracked from the previous test, lets dispose them.
disposeComponents();

// NOTE: Jake: 2018-12-19
// Clear document.body, this is so the first step of 2nd test won't have
// the previous test rendered in it when you're debugging.
Expand All @@ -112,7 +93,7 @@ export class ComponentTester<T = any> {

// private rootView: View;

private host: HTMLTemplateElement | HTMLDivElement | null = null;
// private host: HTMLTemplateElement | HTMLDivElement | null = null;

private html: string = '';

Expand Down Expand Up @@ -206,51 +187,11 @@ export class ComponentTester<T = any> {
document.body.focus();
}

this.host = document.createElement('template');
this.host.innerHTML = this.html;

// Compile the template and copy styles to the main iframe
let view: ViewWithControllers;
const compiler = Container.instance.get(ViewCompiler);
try {
view = compiler.compile(this.host, Container.instance.get(ViewResources)).create(Container.instance);
} catch (err) {
reject(err);
return;
}

if (view.controllers.length > 0) {
this.viewModel = view.controllers[0].viewModel;
if (this.viewModel) {
copyStyles(this.viewModel.constructor.name);
} else {
// tslint:disable-next-line:no-console
console.warn('No view model found on first controller. Styles might not work.', this.html);
}
} else {
// NOTE(Jake): 2018-12-19
// Not sure if/when this case will execute or
// what the ramifications of this are.
copyStyles('undefined');
// tslint:disable-next-line:no-console
console.warn('Unable to determine component name from template. Bugs may occur in cleanup.', this.html);
}

// Clear the document body and add child
while (document.body.firstChild) {
document.body.removeChild(document.body.firstChild);
}
document.body.appendChild(view.fragment);

// NOTE: Jake: 2018-12-20
// Fix aurelia.enhance() problems that are occuring due to
// a <compose> in a component.
// Research: https://github.com/aurelia/framework/issues/600#issuecomment-252479570
// Gist: https://gist.run/?id=c59eed72e1c255b8f462c1d45e495a7a
document.body.querySelectorAll('.au-target').forEach((el) => {
el.classList.remove('au-target');
el.removeAttribute('au-target-id');
});
document.body.innerHTML = this.html;

// NOTE: Jake: 2019-01-31 - #8
// Consider allowing bindingContext to be a function as well.
Expand All @@ -263,6 +204,7 @@ export class ComponentTester<T = any> {
// These are in the original aurelia-testing library
// this.rootView = aurelia.root;
// this.element = this.host.firstElementChild as Element;
copyStyles(this.resources.join(','));

// NOTE: Jake: 2019-01-31 - #9
// We used to call these manually like the aurelia-testing library,
Expand All @@ -275,8 +217,6 @@ export class ComponentTester<T = any> {
// view.attached();
// }

componentsAttached.push(view);

// Wait 4 frames, this allows us to do "hacky" CSS sizing calculations
// that rely on requestAnimationFrame callbacks. This test framework
// supports 4 by default. I might make this configurable in the future
Expand Down
3 changes: 3 additions & 0 deletions src/containerless-div/containerless-div.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<div textcontent.bind="attachedCounter"></div>
</template>
11 changes: 11 additions & 0 deletions src/containerless-div/containerless-div.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { autoinject, containerless } from 'aurelia-framework';

@autoinject
@containerless
export class ContainerlessDiv {
protected attachedCounter = 0;

protected attached(): void {
this.attachedCounter += 1;
}
}

0 comments on commit 7a8b69e

Please sign in to comment.