chore: reduce SauceLabs + Edge flakiness (#1216)

This commit is contained in:
Jeremy Elbourn
2016-09-15 14:16:27 -07:00
committed by GitHub
parent 8eca40b069
commit cdd8e34625
14 changed files with 148 additions and 185 deletions
+12 -12
View File
@@ -23,19 +23,19 @@
"node": ">= 4.2.1 < 5"
},
"dependencies": {
"@angular/common": "2.0.0-rc.6",
"@angular/compiler": "2.0.0-rc.6",
"@angular/core": "2.0.0-rc.6",
"@angular/forms": "2.0.0-rc.6",
"@angular/http": "2.0.0-rc.6",
"@angular/platform-browser": "2.0.0-rc.6",
"@angular/platform-browser-dynamic": "2.0.0-rc.6",
"@angular/router": "3.0.0-rc.2",
"@angular/common": "^2.0.0",
"@angular/compiler": "^2.0.0",
"@angular/core": "^2.0.0",
"@angular/forms": "^2.0.0",
"@angular/http": "^2.0.0",
"@angular/platform-browser": "^2.0.0",
"@angular/platform-browser-dynamic": "^2.0.0",
"@angular/router": "^3.0.0",
"core-js": "^2.4.1",
"hammerjs": "^2.0.8",
"rxjs": "5.0.0-beta.11",
"systemjs": "0.19.31",
"zone.js": "0.6.17"
"rxjs": "5.0.0-beta.12",
"systemjs": "0.19.38",
"zone.js": "^0.6.23"
},
"devDependencies": {
"@angular/compiler-cli": "0.6.0",
@@ -71,7 +71,7 @@
"merge2": "^1.0.2",
"minimist": "^1.2.0",
"node-sass": "^3.4.2",
"protractor": "^3.3.0",
"protractor": "^4.0.8",
"protractor-accessibility-plugin": "0.1.1",
"resolve-bin": "^0.4.0",
"rollup": "^0.34.13",
+4 -4
View File
@@ -46,7 +46,7 @@ describe('MdButtonToggle', () => {
let buttonToggleInstances: MdButtonToggle[];
let testComponent: ButtonTogglesInsideButtonToggleGroup;
beforeEach(async(() => {
beforeEach(() => {
fixture = TestBed.createComponent(ButtonTogglesInsideButtonToggleGroup);
fixture.detectChanges();
@@ -65,7 +65,7 @@ describe('MdButtonToggle', () => {
.map(debugEl => debugEl.nativeElement);
buttonToggleInstances = buttonToggleDebugElements.map(debugEl => debugEl.componentInstance);
}));
});
it('should set individual button toggle names based on the group name', () => {
expect(groupInstance.name).toBeTruthy();
@@ -326,7 +326,7 @@ describe('MdButtonToggle', () => {
describe('with initial value and change event', () => {
it('should not fire an initial change event', async(() => {
it('should not fire an initial change event', () => {
let fixture = TestBed.createComponent(ButtonToggleGroupWithInitialValue);
let testComponent = fixture.debugElement.componentInstance;
let groupDebugElement = fixture.debugElement.query(By.directive(MdButtonToggleGroup));
@@ -342,7 +342,7 @@ describe('MdButtonToggle', () => {
expect(groupInstance.value).toBe('green');
expect(testComponent.lastEvent.value).toBe('green');
}));
});
});
+22 -22
View File
@@ -45,7 +45,7 @@ describe('MdCheckbox', () => {
let inputElement: HTMLInputElement;
let labelElement: HTMLLabelElement;
beforeEach(async(() => {
beforeEach(() => {
fixture = TestBed.createComponent(SingleCheckbox);
fixture.detectChanges();
@@ -55,7 +55,7 @@ describe('MdCheckbox', () => {
testComponent = fixture.debugElement.componentInstance;
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
labelElement = <HTMLLabelElement>checkboxNativeElement.querySelector('label');
}));
});
it('should add and remove the checked state', () => {
expect(checkboxInstance.checked).toBe(false);
@@ -318,7 +318,7 @@ describe('MdCheckbox', () => {
let inputElement: HTMLInputElement;
let labelElement: HTMLLabelElement;
beforeEach(async(() => {
beforeEach(() => {
fixture = TestBed.createComponent(CheckboxWithChangeEvent);
fixture.detectChanges();
@@ -328,7 +328,7 @@ describe('MdCheckbox', () => {
testComponent = fixture.debugElement.componentInstance;
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
labelElement = <HTMLLabelElement>checkboxNativeElement.querySelector('label');
}));
});
it('should emit the event to the change observable', () => {
let changeSpy = jasmine.createSpy('onChangeObservable');
@@ -370,7 +370,7 @@ describe('MdCheckbox', () => {
let checkboxNativeElement: HTMLElement;
let inputElement: HTMLInputElement;
it('should use the provided aria-label', async(() => {
it('should use the provided aria-label', () => {
fixture = TestBed.createComponent(CheckboxWithAriaLabel);
checkboxDebugElement = fixture.debugElement.query(By.directive(MdCheckbox));
checkboxNativeElement = checkboxDebugElement.nativeElement;
@@ -378,7 +378,7 @@ describe('MdCheckbox', () => {
fixture.detectChanges();
expect(inputElement.getAttribute('aria-label')).toBe('Super effective');
}));
});
});
describe('with provided aria-labelledby ', () => {
@@ -386,7 +386,7 @@ describe('MdCheckbox', () => {
let checkboxNativeElement: HTMLElement;
let inputElement: HTMLInputElement;
it('should use the provided aria-labelledby', async(() => {
it('should use the provided aria-labelledby', () => {
fixture = TestBed.createComponent(CheckboxWithAriaLabelledby);
checkboxDebugElement = fixture.debugElement.query(By.directive(MdCheckbox));
checkboxNativeElement = checkboxDebugElement.nativeElement;
@@ -394,9 +394,9 @@ describe('MdCheckbox', () => {
fixture.detectChanges();
expect(inputElement.getAttribute('aria-labelledby')).toBe('some-id');
}));
});
it('should not assign aria-labelledby if none is provided', async(() => {
it('should not assign aria-labelledby if none is provided', () => {
fixture = TestBed.createComponent(SingleCheckbox);
checkboxDebugElement = fixture.debugElement.query(By.directive(MdCheckbox));
checkboxNativeElement = checkboxDebugElement.nativeElement;
@@ -404,7 +404,7 @@ describe('MdCheckbox', () => {
fixture.detectChanges();
expect(inputElement.getAttribute('aria-labelledby')).toBe(null);
}));
});
});
describe('with provided tabIndex', () => {
@@ -414,7 +414,7 @@ describe('MdCheckbox', () => {
let inputElement: HTMLInputElement;
let labelElement: HTMLLabelElement;
beforeEach(async(() => {
beforeEach(() => {
fixture = TestBed.createComponent(CheckboxWithTabIndex);
fixture.detectChanges();
@@ -423,11 +423,11 @@ describe('MdCheckbox', () => {
checkboxNativeElement = checkboxDebugElement.nativeElement;
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
labelElement = <HTMLLabelElement>checkboxNativeElement.querySelector('label');
}));
});
it('should preserve any given tabIndex', async(() => {
it('should preserve any given tabIndex', () => {
expect(inputElement.tabIndex).toBe(7);
}));
});
it('should preserve given tabIndex when the checkbox is disabled then enabled', () => {
testComponent.isDisabled = true;
@@ -444,10 +444,10 @@ describe('MdCheckbox', () => {
});
describe('with multiple checkboxes', () => {
beforeEach(async(() => {
beforeEach(() => {
fixture = TestBed.createComponent(MultipleCheckboxes);
fixture.detectChanges();
}));
});
it('should assign a unique id to each checkbox', () => {
let [firstId, secondId] =
@@ -461,10 +461,10 @@ describe('MdCheckbox', () => {
});
describe('with ngModel', () => {
beforeEach(async(() => {
beforeEach(() => {
fixture = TestBed.createComponent(CheckboxWithFormDirectives);
fixture.detectChanges();
}));
});
it('should be in pristine, untouched, and valid states initially', fakeAsync(() => {
flushMicrotasks();
@@ -482,17 +482,17 @@ describe('MdCheckbox', () => {
});
describe('with name attribute', () => {
beforeEach(async(() => {
beforeEach(() => {
fixture = TestBed.createComponent(CheckboxWithNameAttribute);
fixture.detectChanges();
}));
});
it('should forward name value to input element', fakeAsync(() => {
it('should forward name value to input element', () => {
let checkboxElement = fixture.debugElement.query(By.directive(MdCheckbox));
let inputElement = <HTMLInputElement> checkboxElement.nativeElement.querySelector('input');
expect(inputElement.getAttribute('name')).toBe('test-name');
}));
});
});
});
@@ -1,4 +1,4 @@
import {async, fakeAsync, flushMicrotasks, ComponentFixture, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {Component, ViewChild} from '@angular/core';
import {ConnectedOverlayDirective, OverlayModule} from './overlay-directives';
import {OverlayContainer} from './overlay-container';
@@ -9,7 +9,7 @@ describe('Overlay directives', () => {
let overlayContainerElement: HTMLElement;
let fixture: ComponentFixture<ConnectedOverlayDirectiveTest>;
beforeEach(async(() => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [OverlayModule.forRoot()],
declarations: [ConnectedOverlayDirectiveTest],
@@ -20,23 +20,22 @@ describe('Overlay directives', () => {
}}
],
});
}));
});
beforeEach(async(() => {
beforeEach(() => {
fixture = TestBed.createComponent(ConnectedOverlayDirectiveTest);
fixture.detectChanges();
}));
});
it(`should create an overlay and attach the directive's template`, () => {
expect(overlayContainerElement.textContent).toContain('Menu content');
});
it('should destroy the overlay when the directive is destroyed', fakeAsync(() => {
it('should destroy the overlay when the directive is destroyed', () => {
fixture.destroy();
flushMicrotasks();
expect(overlayContainerElement.textContent.trim()).toBe('');
}));
});
it('should use a connected position strategy with a default set of positions', () => {
let testComponent: ConnectedOverlayDirectiveTest =
+26 -73
View File
@@ -1,11 +1,4 @@
import {
inject,
fakeAsync,
flushMicrotasks,
ComponentFixture,
TestBed,
async,
} from '@angular/core/testing';
import {inject, ComponentFixture, TestBed, async} from '@angular/core/testing';
import {
NgModule,
Component,
@@ -34,25 +27,22 @@ describe('Portals', () => {
describe('PortalHostDirective', () => {
let fixture: ComponentFixture<PortalTestApp>;
beforeEach(fakeAsync(() => {
beforeEach(() => {
fixture = TestBed.createComponent(PortalTestApp);
}));
});
it('should load a component into the portal', fakeAsync(() => {
it('should load a component into the portal', () => {
// Set the selectedHost to be a ComponentPortal.
let testAppComponent = fixture.debugElement.componentInstance;
testAppComponent.selectedPortal = new ComponentPortal(PizzaMsg);
fixture.detectChanges();
// Flush the attachment of the Portal.
flushMicrotasks();
// Expect that the content of the attached portal is present.
let hostContainer = fixture.nativeElement.querySelector('.portal-container');
expect(hostContainer.textContent).toContain('Pizza');
}));
});
it('should load a component into the portal with a given injector', fakeAsync(() => {
it('should load a component into the portal with a given injector', () => {
// Create a custom injector for the component.
let chocolateInjector = new ChocolateInjector(fixture.componentInstance.injector);
@@ -61,17 +51,13 @@ describe('Portals', () => {
testAppComponent.selectedPortal = new ComponentPortal(PizzaMsg, null, chocolateInjector);
fixture.detectChanges();
// Flush the attachment of the Portal.
flushMicrotasks();
fixture.detectChanges();
// Expect that the content of the attached portal is present.
let hostContainer = fixture.nativeElement.querySelector('.portal-container');
expect(hostContainer.textContent).toContain('Pizza');
expect(hostContainer.textContent).toContain('Chocolate');
}));
});
it('should load a <template> portal', fakeAsync(() => {
it('should load a <template> portal', () => {
let testAppComponent = fixture.debugElement.componentInstance;
// Detect changes initially so that the component's ViewChildren are resolved.
@@ -81,15 +67,12 @@ describe('Portals', () => {
testAppComponent.selectedPortal = testAppComponent.cakePortal;
fixture.detectChanges();
// Flush the attachment of the Portal.
flushMicrotasks();
// Expect that the content of the attached portal is present.
let hostContainer = fixture.nativeElement.querySelector('.portal-container');
expect(hostContainer.textContent).toContain('Cake');
}));
});
it('should load a <template> portal with the `*` sugar', fakeAsync(() => {
it('should load a <template> portal with the `*` sugar', () => {
let testAppComponent = fixture.debugElement.componentInstance;
// Detect changes initially so that the component's ViewChildren are resolved.
@@ -99,15 +82,12 @@ describe('Portals', () => {
testAppComponent.selectedPortal = testAppComponent.piePortal;
fixture.detectChanges();
// Flush the attachment of the Portal.
flushMicrotasks();
// Expect that the content of the attached portal is present.
let hostContainer = fixture.nativeElement.querySelector('.portal-container');
expect(hostContainer.textContent).toContain('Pie');
}));
});
it('should load a <template> portal with a binding', fakeAsync(() => {
it('should load a <template> portal with a binding', () => {
let testAppComponent = fixture.debugElement.componentInstance;
// Detect changes initially so that the component's ViewChildren are resolved.
@@ -117,13 +97,6 @@ describe('Portals', () => {
testAppComponent.selectedPortal = testAppComponent.portalWithBinding;
fixture.detectChanges();
// Flush the attachment of the Portal.
flushMicrotasks();
// Now that the portal is attached, change detection has to happen again in order
// for the bindings to update.
fixture.detectChanges();
// Expect that the content of the attached portal is present.
let hostContainer = fixture.nativeElement.querySelector('.portal-container');
expect(hostContainer.textContent).toContain('Banana');
@@ -134,9 +107,9 @@ describe('Portals', () => {
// Expect the new value to be reflected in the rendered output.
expect(hostContainer.textContent).toContain('Mango');
}));
});
it('should change the attached portal', fakeAsync(() => {
it('should change the attached portal', () => {
let testAppComponent = fixture.debugElement.componentInstance;
// Detect changes initially so that the component's ViewChildren are resolved.
@@ -146,10 +119,6 @@ describe('Portals', () => {
testAppComponent.selectedPortal = testAppComponent.piePortal;
fixture.detectChanges();
// Flush the attachment of the Portal.
flushMicrotasks();
fixture.detectChanges();
// Expect that the content of the attached portal is present.
let hostContainer = fixture.nativeElement.querySelector('.portal-container');
expect(hostContainer.textContent).toContain('Pie');
@@ -157,13 +126,11 @@ describe('Portals', () => {
testAppComponent.selectedPortal = new ComponentPortal(PizzaMsg);
fixture.detectChanges();
flushMicrotasks();
expect(hostContainer.textContent).toContain('Pizza');
}));
});
});
describe('DomPortalHost', function () {
describe('DomPortalHost', () => {
let componentFactoryResolver: ComponentFactoryResolver;
let someViewContainerRef: ViewContainerRef;
let someInjector: Injector;
@@ -183,23 +150,20 @@ describe('Portals', () => {
someInjector = fixture.componentInstance.injector;
});
it('should attach and detach a component portal', fakeAsync(() => {
it('should attach and detach a component portal', () => {
let portal = new ComponentPortal(PizzaMsg, someViewContainerRef);
let componentInstance: PizzaMsg = portal.attach(host).instance;
flushMicrotasks();
expect(componentInstance).toEqual(jasmine.any(PizzaMsg));
expect(someDomElement.textContent).toContain('Pizza');
host.detach();
flushMicrotasks();
expect(someDomElement.innerHTML).toBe('');
}));
});
it('should attach and detach a component portal with a given injector', fakeAsync(() => {
it('should attach and detach a component portal with a given injector', () => {
let fixture = TestBed.createComponent(ArbitraryViewContainerRefComponent);
someViewContainerRef = fixture.componentInstance.viewContainerRef;
someInjector = fixture.componentInstance.injector;
@@ -208,8 +172,6 @@ describe('Portals', () => {
let portal = new ComponentPortal(PizzaMsg, someViewContainerRef, chocolateInjector);
let componentInstance: PizzaMsg = portal.attach(host).instance;
flushMicrotasks();
fixture.detectChanges();
expect(componentInstance).toEqual(jasmine.any(PizzaMsg));
@@ -217,22 +179,20 @@ describe('Portals', () => {
expect(someDomElement.textContent).toContain('Chocolate');
host.detach();
flushMicrotasks();
expect(someDomElement.innerHTML).toBe('');
}));
});
it('should attach and detach a template portal', fakeAsync(() => {
it('should attach and detach a template portal', () => {
let fixture = TestBed.createComponent(PortalTestApp);
fixture.detectChanges();
fixture.componentInstance.cakePortal.attach(host);
flushMicrotasks();
expect(someDomElement.textContent).toContain('Cake');
}));
});
it('should attach and detach a template portal with a binding', fakeAsync(() => {
it('should attach and detach a template portal with a binding', () => {
let fixture = TestBed.createComponent(PortalTestApp);
let testAppComponent = fixture.debugElement.componentInstance;
@@ -244,9 +204,6 @@ describe('Portals', () => {
testAppComponent.portalWithBinding.attach(host);
fixture.detectChanges();
// Flush the attachment of the Portal.
flushMicrotasks();
// Now that the portal is attached, change detection has to happen again in order
// for the bindings to update.
fixture.detectChanges();
@@ -263,9 +220,9 @@ describe('Portals', () => {
host.detach();
expect(someDomElement.innerHTML).toBe('');
}));
});
it('should change the attached portal', fakeAsync(() => {
it('should change the attached portal', () => {
let fixture = TestBed.createComponent(ArbitraryViewContainerRefComponent);
someViewContainerRef = fixture.componentInstance.viewContainerRef;
@@ -273,18 +230,14 @@ describe('Portals', () => {
appFixture.detectChanges();
appFixture.componentInstance.piePortal.attach(host);
flushMicrotasks();
expect(someDomElement.textContent).toContain('Pie');
host.detach();
flushMicrotasks();
host.attach(new ComponentPortal(PizzaMsg, someViewContainerRef));
flushMicrotasks();
expect(someDomElement.textContent).toContain('Pizza');
}));
});
});
});
+8 -8
View File
@@ -70,7 +70,7 @@ describe('MdInput', function () {
expect(fixture.debugElement.query(By.css('input'))).toBeTruthy();
});
it('should not be treated as empty if type is date', async(() => {
it('should not be treated as empty if type is date', () => {
if (isInternetExplorer11()) {
return;
}
@@ -81,9 +81,9 @@ describe('MdInput', function () {
let el = fixture.debugElement.query(By.css('label')).nativeElement;
expect(el).not.toBeNull();
expect(el.className.includes('md-empty')).toBe(false);
}));
});
it('should treat text input type as empty at init', async(() => {
it('should treat text input type as empty at init', () => {
if (isInternetExplorer11()) {
return;
}
@@ -94,9 +94,9 @@ describe('MdInput', function () {
let el = fixture.debugElement.query(By.css('label')).nativeElement;
expect(el).not.toBeNull();
expect(el.className.includes('md-empty')).toBe(true);
}));
});
it('should treat password input type as empty at init', async(() => {
it('should treat password input type as empty at init', () => {
if (isInternetExplorer11()) {
return;
}
@@ -107,9 +107,9 @@ describe('MdInput', function () {
let el = fixture.debugElement.query(By.css('label')).nativeElement;
expect(el).not.toBeNull();
expect(el.className.includes('md-empty')).toBe(true);
}));
});
it('should treat number input type as empty at init', async(() => {
it('should treat number input type as empty at init', () => {
if (isInternetExplorer11()) {
return;
}
@@ -120,7 +120,7 @@ describe('MdInput', function () {
let el = fixture.debugElement.query(By.css('label')).nativeElement;
expect(el).not.toBeNull();
expect(el.className.includes('md-empty')).toBe(true);
}));
});
// TODO(kara): update when core/testing adds fix
it('support ngModel', async(() => {
+11 -11
View File
@@ -1,4 +1,4 @@
import {async, fakeAsync, ComponentFixture, TestBed} from '@angular/core/testing';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {NgControl, FormsModule} from '@angular/forms';
import {Component, DebugElement} from '@angular/core';
import {By} from '@angular/platform-browser';
@@ -130,7 +130,7 @@ describe('MdRadio', () => {
expect(groupInstance.selected).toBe(radioInstances[0]);
});
it('should emit a change event from radio buttons', fakeAsync(() => {
it('should emit a change event from radio buttons', () => {
expect(radioInstances[0].checked).toBe(false);
let spies = radioInstances
@@ -150,9 +150,9 @@ describe('MdRadio', () => {
// be triggered when the radio got unselected.
expect(spies[0]).toHaveBeenCalledTimes(1);
expect(spies[1]).toHaveBeenCalledTimes(1);
}));
});
it('should emit a change event from the radio group', fakeAsync(() => {
it('should emit a change event from the radio group', () => {
expect(groupInstance.value).toBeFalsy();
let changeSpy = jasmine.createSpy('radio-group change listener');
@@ -167,7 +167,7 @@ describe('MdRadio', () => {
fixture.detectChanges();
expect(changeSpy).toHaveBeenCalledTimes(2);
}));
});
// TODO(jelbourn): test this in an e2e test with *real* focus, rather than faking
// a focus / blur event.
@@ -274,7 +274,7 @@ describe('MdRadio', () => {
expect(groupInstance.selected.value).toBe(groupInstance.value);
});
it('should have the correct control state initially and after interaction', fakeAsync(() => {
it('should have the correct control state initially and after interaction', () => {
// The control should start off valid, pristine, and untouched.
expect(groupNgControl.valid).toBe(true);
expect(groupNgControl.pristine).toBe(true);
@@ -297,16 +297,16 @@ describe('MdRadio', () => {
expect(groupNgControl.valid).toBe(true);
expect(groupNgControl.pristine).toBe(false);
expect(groupNgControl.touched).toBe(true);
}));
});
it('should update the ngModel value when selecting a radio button', fakeAsync(() => {
it('should update the ngModel value when selecting a radio button', () => {
radioInstances[1].checked = true;
fixture.detectChanges();
expect(testComponent.modelValue).toBe('chocolate');
}));
});
it('should update the model before firing change event', fakeAsync(() => {
it('should update the model before firing change event', () => {
expect(testComponent.modelValue).toBeUndefined();
expect(testComponent.lastEvent).toBeUndefined();
@@ -321,7 +321,7 @@ describe('MdRadio', () => {
expect(testComponent.modelValue).toBe('vanilla');
expect(testComponent.lastEvent.value).toBe('vanilla');
}));
});
});
describe('as standalone', () => {
+7 -21
View File
@@ -116,11 +116,10 @@ describe('MdSlideToggle', () => {
expect(slideToggleElement.classList).toContain('md-checked');
expect(slideToggle.checked).toBe(true);
expect(testComponent.onSlideClick).toHaveBeenCalledTimes(1);
});
it('should trigger the change event properly', async(() => {
it('should trigger the change event properly', () => {
expect(inputElement.checked).toBe(false);
expect(slideToggleElement.classList).not.toContain('md-checked');
@@ -129,16 +128,8 @@ describe('MdSlideToggle', () => {
expect(inputElement.checked).toBe(true);
expect(slideToggleElement.classList).toContain('md-checked');
// Wait for the fixture to become stable, because the EventEmitter for the change event,
// will only fire after the zone async change detection has finished.
fixture.whenStable().then(() => {
// The change event shouldn't fire, because the value change was not caused
// by any interaction.
expect(testComponent.onSlideChange).toHaveBeenCalledTimes(1);
});
}));
expect(testComponent.onSlideChange).toHaveBeenCalledTimes(1);
});
it('should not trigger the change event by changing the native value', async(() => {
expect(inputElement.checked).toBe(false);
@@ -150,14 +141,11 @@ describe('MdSlideToggle', () => {
expect(inputElement.checked).toBe(true);
expect(slideToggleElement.classList).toContain('md-checked');
// Wait for the fixture to become stable, because the EventEmitter for the change event,
// will only fire after the zone async change detection has finished.
// The change event shouldn't fire because the value change was not caused
// by any interaction. Use whenStable to ensure an event isn't fired asynchronously.
fixture.whenStable().then(() => {
// The change event shouldn't fire, because the value change was not caused
// by any interaction.
expect(testComponent.onSlideChange).not.toHaveBeenCalled();
});
}));
it('should not trigger the change event on initialization', async(() => {
@@ -170,13 +158,11 @@ describe('MdSlideToggle', () => {
expect(inputElement.checked).toBe(true);
expect(slideToggleElement.classList).toContain('md-checked');
// Wait for the fixture to become stable, because the EventEmitter for the change event,
// will only fire after the zone async change detection has finished.
// The change event shouldn't fire, because the native input element is not focused.
// Use whenStable to ensure an event isn't fired asynchronously.
fixture.whenStable().then(() => {
// The change event shouldn't fire, because the native input element is not focused.
expect(testComponent.onSlideChange).not.toHaveBeenCalled();
});
}));
it('should add a suffix to the inputs id', () => {
+4 -4
View File
@@ -322,7 +322,7 @@ describe('MdSlider', () => {
let sliderInstance: MdSlider;
let sliderTrackElement: HTMLElement;
beforeEach(async(() => {
beforeEach(() => {
fixture = TestBed.createComponent(SliderWithValue);
fixture.detectChanges();
@@ -330,7 +330,7 @@ describe('MdSlider', () => {
sliderNativeElement = sliderDebugElement.nativeElement;
sliderInstance = sliderDebugElement.injector.get(MdSlider);
sliderTrackElement = <HTMLElement>sliderNativeElement.querySelector('.md-slider-track');
}));
});
it('should set the default value from the attribute', () => {
expect(sliderInstance.value).toBe(26);
@@ -425,7 +425,7 @@ describe('MdSlider', () => {
let tickContainer: HTMLElement;
let lastTickContainer: HTMLElement;
beforeEach(async(() => {
beforeEach(() => {
fixture = TestBed.createComponent(SliderWithAutoTickInterval);
fixture.detectChanges();
@@ -434,7 +434,7 @@ describe('MdSlider', () => {
tickContainer = <HTMLElement>sliderNativeElement.querySelector('.md-slider-tick-container');
lastTickContainer =
<HTMLElement>sliderNativeElement.querySelector('.md-slider-last-tick-container');
}));
});
it('should set the correct tick separation', () => {
// The first tick mark is going to be at value 30 as it is the first step after 30px. The
+6 -6
View File
@@ -23,15 +23,15 @@ describe('MdTabGroup', () => {
describe('basic behavior', () => {
let fixture: ComponentFixture<SimpleTabsTestApp>;
beforeEach(async(() => {
beforeEach(() => {
fixture = TestBed.createComponent(SimpleTabsTestApp);
}));
});
it('should default to the first tab', async(() => {
it('should default to the first tab', () => {
checkSelectedIndex(1, fixture);
}));
});
it('should change selected index on click', async(() => {
it('should change selected index on click', () => {
let component = fixture.debugElement.componentInstance;
component.selectedIndex = 0;
checkSelectedIndex(0, fixture);
@@ -45,7 +45,7 @@ describe('MdTabGroup', () => {
tabLabel = fixture.debugElement.queryAll(By.css('.md-tab-label'))[2];
tabLabel.nativeElement.click();
checkSelectedIndex(2, fixture);
}));
});
it('should support two-way binding for selectedIndex', async(() => {
let component = fixture.componentInstance;
+2
View File
@@ -37,6 +37,8 @@ System.import(distPath + '@angular2-material/system-config-spec.js').then(functi
var testing = providers[0];
var testingBrowser = providers[1];
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
testing.TestBed.initTestEnvironment(
testingBrowser.BrowserDynamicTestingModule,
testingBrowser.platformBrowserDynamicTesting());
+15 -4
View File
@@ -3,7 +3,7 @@ import {readdirSync, statSync, writeFileSync} from 'fs';
import * as path from 'path';
import {SOURCE_ROOT, DIST_COMPONENTS_ROOT, PROJECT_ROOT} from '../constants';
import {sassBuildTask, tsBuildTask, execNodeTask, copyTask} from '../task_helpers';
import {sassBuildTask, tsBuildTask, execNodeTask, copyTask, sequenceTask} from '../task_helpers';
// No typings for these.
const inlineResources = require('../../../scripts/release/inline-resources');
@@ -25,6 +25,12 @@ task(':watch:components', () => {
watch(path.join(componentsDir, '**/*.html'), [':build:components:assets']);
});
task(':watch:components:spec', () => {
watch(path.join(componentsDir, '**/*.ts'), [':build:components:spec']);
watch(path.join(componentsDir, '**/*.scss'), [':build:components:scss']);
watch(path.join(componentsDir, '**/*.html'), [':build:components:assets']);
});
task(':build:components:ts', tsBuildTask(componentsDir));
task(':build:components:spec', tsBuildTask(path.join(componentsDir, 'tsconfig-spec.json')));
@@ -88,12 +94,17 @@ task(':build:components:rollup', [':build:components:ts'], () => {
}, Promise.resolve());
});
task('build:components', [
task('build:components', sequenceTask(
':build:components:rollup',
':build:components:assets',
':build:components:scss'
], () => inlineResources([DIST_COMPONENTS_ROOT]));
':build:components:scss',
':inline-resources',
));
task(':build:components:ngc', ['build:components'], execNodeTask(
'@angular/compiler-cli', 'ngc', ['-p', path.relative(PROJECT_ROOT, path.join(componentsDir, 'tsconfig.json'))]
));
task(':inline-resources', () => {
inlineResources([DIST_COMPONENTS_ROOT]);
});
+7 -4
View File
@@ -3,7 +3,7 @@ import * as path from 'path';
import gulpMerge = require('merge2');
import gulpRunSequence = require('run-sequence');
import {SOURCE_ROOT, DIST_ROOT, PROJECT_ROOT, NPM_VENDOR_FILES} from '../constants';
import {SOURCE_ROOT, DIST_ROOT, PROJECT_ROOT} from '../constants';
import {
tsBuildTask, sassBuildTask, copyTask, buildAppTask, execNodeTask,
vendorTask, sequenceTask, serverTask
@@ -41,13 +41,16 @@ let stopE2eServer: () => void = null;
task(':serve:e2eapp', serverTask(false, (stream) => { stopE2eServer = () => stream.emit('kill') }));
task(':serve:e2eapp:stop', () => stopE2eServer());
task('serve:e2eapp', ['build:e2eapp'], sequenceTask([
':inline-resources',
':serve:e2eapp',
':watch:components',
':watch:e2eapp'
]));
task('e2e', sequenceTask(
':test:protractor:setup', 'serve:e2eapp', ':test:protractor', ':serve:e2eapp:stop',
':e2e:done'
':test:protractor:setup',
'serve:e2eapp',
':test:protractor',
':serve:e2eapp:stop',
':e2e:done',
));
+17 -8
View File
@@ -1,11 +1,12 @@
import gulp = require('gulp');
const karma = require('karma');
import path = require('path');
import gulpMerge = require('merge2');
import {PROJECT_ROOT} from '../constants';
import {PROJECT_ROOT, DIST_COMPONENTS_ROOT} from '../constants';
import {sequenceTask} from '../task_helpers';
const karma = require('karma');
const runSequence = require('run-sequence');
gulp.task(':build:test:vendor', function() {
const npmVendorFiles = [
@@ -23,8 +24,11 @@ gulp.task(':build:test:vendor', function() {
gulp.task(':test:deps', sequenceTask(
'clean',
[
':build:test:vendor', ':build:components:assets', ':build:components:scss',
':build:components:spec'
':build:test:vendor',
':build:components:assets',
':build:components:scss',
':build:components:spec',
':watch:components:spec',
]
));
@@ -33,9 +37,14 @@ gulp.task('test', [':test:deps'], (done: () => void) => {
configFile: path.join(PROJECT_ROOT, 'test/karma.conf.js')
}, done).start();
});
gulp.task('test:single-run', [':test:deps'], (done: () => void) => {
new karma.Server({
configFile: path.join(PROJECT_ROOT, 'test/karma.conf.js'),
singleRun: true
}, done).start();
runSequence(
':inline-resources',
() => {
new karma.Server({
configFile: path.join(PROJECT_ROOT, 'test/karma.conf.js'),
singleRun: true
}, done).start();
});
});