Skip to content

Commit 32e8c06

Browse files
committed
test(ImageLoader): more fixes for flaky e2e tests
1 parent ef638e8 commit 32e8c06

File tree

4 files changed

+141
-86
lines changed

4 files changed

+141
-86
lines changed

e2e/app.po.ts

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,23 @@ export class AppPage {
1212
.then((posY) => posY === y));
1313
}
1414

15-
scrollToBottom() {
16-
browser.executeScript(`return window.scrollTo(0, document.documentElement.offsetHeight);`);
15+
scrollIntoView(selector: string) {
16+
return browser.executeScript(`return document.querySelector('${selector}').scrollIntoView()`);
17+
}
18+
19+
scrollToImageTopElement() {
20+
this.scrollIntoView('.sn-image-loader--top');
21+
return this.waitForImageTopElementLoaded();
22+
}
23+
24+
scrollToImageBottomElement() {
25+
this.scrollIntoView('.sn-image-loader--bottom');
26+
return this.waitForImageBottomElementLoaded();
27+
}
28+
29+
scrollToVideoElement() {
30+
this.scrollIntoView('sn-video-loader');
31+
return this.waitForVideoLoaded();
1732
}
1833

1934
setWindowSize(x: number, y: number) {
@@ -27,10 +42,6 @@ export class AppPage {
2742
return browser.executeScript(`return { height: window.outerHeight, width: window.outerWidth };`);
2843
}
2944

30-
getDocumentHeight() {
31-
return browser.executeScript(`return document.documentElement.offsetHeight;`);
32-
}
33-
3445
getScrollYPosition() {
3546
return browser.executeScript('return window.pageYOffset;');
3647
}
@@ -43,6 +54,15 @@ export class AppPage {
4354
return element(by.css('.sn-image-loader--bottom'));
4455
}
4556

57+
58+
getImageTopLoaderCompClass() {
59+
return this.getImageTopLoaderComp().getAttribute('class');
60+
}
61+
62+
getImageBottomLoaderCompClass() {
63+
return this.getImageBottomLoaderComp().getAttribute('class');
64+
}
65+
4666
getImageTopElement() {
4767
return element(by.css('.sn-image-loader--top .img'));
4868
}
@@ -51,28 +71,36 @@ export class AppPage {
5171
return element(by.css('.sn-image-loader--bottom .img'));
5272
}
5373

54-
getImageBottomElementSrcSet() {
55-
return this.getImageBottomElement().getAttribute('srcset');
74+
getImageTopElementSrc() {
75+
return this.getImageTopElement().getAttribute('src');
76+
}
77+
78+
getImageTopElementSrcSet() {
79+
return this.getImageTopElement().getAttribute('srcset');
5680
}
5781

58-
getLoadedImageBottomElement() {
59-
return element(by.css('.sn-image-loader--bottom.sn-image-loaded')).isPresent();
82+
getImageBottomElementSrc() {
83+
return this.getImageBottomElement().getAttribute('src');
84+
}
85+
86+
getImageBottomElementSrcSet() {
87+
return this.getImageBottomElement().getAttribute('srcset');
6088
}
6189

62-
getLoadedImageTopElement() {
63-
return element(by.css('.sn-image-loader--top.sn-image-loaded')).isPresent();
90+
getImageBottomPlaceholderLoadedElement() {
91+
return element(by.css('.placeholder-loaded'));
6492
}
6593

66-
getLoadedImageElementBySrcSet(srcSet) {
67-
return element(by.css(`.img--bottom[srcSet="${srcSet}"]`)).isPresent();
94+
getImageBottomPlaceholderLoadedElementText() {
95+
return this.getImageBottomPlaceholderLoadedElement().getText();
6896
}
6997

70-
getBottomPlaceholderBooleanElement() {
71-
return element(by.css('.placeholder-boolean'));
98+
getImageBottomLoadedCountElement() {
99+
return element(by.css('.image-loaded-count'));
72100
}
73101

74-
getBottomFullResCountElement() {
75-
return element(by.css('.full-res-count'));
102+
getImageBottomLoadedCountElementText() {
103+
return this.getImageBottomLoadedCountElement().getText();
76104
}
77105

78106
getVideoElement() {
@@ -87,13 +115,27 @@ export class AppPage {
87115
return this.getVideoElement().getAttribute('class');
88116
}
89117

118+
isImageTopLoaded() {
119+
return this.getImageTopLoaderCompClass()
120+
.then((result: string) => result.includes('sn-image-loaded'));
121+
}
122+
123+
isImageBottomLoaded() {
124+
return this.getImageBottomLoaderCompClass()
125+
.then((result: string) => result.includes('sn-image-loaded'));
126+
}
127+
90128
isVideoLoaded() {
91129
return this.getVideoElementClass()
92130
.then((result: string) => result.includes('sn-video-loaded'));
93131
}
94132

133+
waitForImageTopElementLoaded() {
134+
browser.wait(() => this.isImageTopLoaded());
135+
}
136+
95137
waitForImageBottomElementLoaded() {
96-
browser.wait(() => this.getLoadedImageBottomElement());
138+
browser.wait(() => this.isImageBottomLoaded());
97139
}
98140

99141
waitForVideoLoaded() {

e2e/image-loader.e2e-spec.ts

Lines changed: 74 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import { image } from '../src/app/app-data';
55
describe('ImageLoader Lib E2E Tests', function () {
66
let page: AppPage;
77

8-
const browserWaitTimeout = 10000;
9-
108
beforeEach(() => {
119
page = new AppPage();
1210
page.navigateTo();
@@ -26,27 +24,30 @@ describe('ImageLoader Lib E2E Tests', function () {
2624
describe('placeholder image', () => {
2725
beforeEach(() => page.setWindowSize(400, 580));
2826

29-
it('should load placeholder image', () => {
30-
expect(page.getImageBottomElement().getAttribute('src')).toEqual('http://via.placeholder.com/40x40?text=placeholder');
27+
it('should set src to placeholder image', () => {
28+
const result = page.getImageBottomElementSrc();
29+
const expected = image.placeholder;
30+
expect(result).toEqual(expected);
3131
});
3232

33-
it('should update placeholder loaded boolean on init', () => {
34-
expect(page.getBottomPlaceholderBooleanElement().getText()).toEqual('true');
33+
it('should set placeholder loaded text to true on init', () => {
34+
const result = page.getImageBottomPlaceholderLoadedElementText();
35+
const expected = 'true';
36+
expect(result).toEqual(expected);
3537
});
3638
});
3739

38-
describe('inviewport image on load', () => {
40+
describe('image in viewport on page load', () => {
3941
beforeEach(() => page.setWindowSize(400, 580));
4042

41-
it('should load full res image if image is in viewport on page load', () => {
42-
browser.wait(() => page.getLoadedImageTopElement());
43-
44-
const imageLoaderCompClass = page.getImageTopLoaderComp().getAttribute('class');
45-
const imgSrc = page.getImageTopElement().getAttribute('srcset');
46-
expect(imageLoaderCompClass).toContain('sn-image-loaded');
47-
expect(imgSrc).toEqual('http://via.placeholder.com/400x400?text=xs+1x 1x, http://via.placeholder.com/800x800?text=xs+2x 2x');
48-
43+
it('should load image when in viewport on page load', () => {
44+
page.waitForImageTopElementLoaded();
4945

46+
const resultLoaded = page.isImageTopLoaded();
47+
const resultSrcset = page.getImageTopElementSrcSet();
48+
const expectedSrcset = `${image.images[0].x1} 1x, ${image.images[0].x2} 2x`;
49+
expect(resultLoaded).toBeTruthy();
50+
expect(resultSrcset).toEqual(expectedSrcset);
5051
});
5152

5253
});
@@ -55,27 +56,28 @@ describe('ImageLoader Lib E2E Tests', function () {
5556
beforeEach(() => page.setWindowSize(400, 580));
5657

5758
it('should load image when scrolled into viewport', () => {
58-
let imageLoaderCompClass = page.getImageBottomLoaderComp().getAttribute('class');
59-
let imgSrc = page.getImageBottomElement().getAttribute('src');
60-
expect(imageLoaderCompClass).toContain('sn-image-not-loaded');
61-
expect(imgSrc).toEqual('http://via.placeholder.com/40x40?text=placeholder');
62-
63-
page.scrollTo(0, 580 * 2);
64-
browser.wait(() => page.getLoadedImageBottomElement());
65-
66-
imageLoaderCompClass = page.getImageBottomLoaderComp().getAttribute('class');
67-
imgSrc = page.getImageBottomElement().getAttribute('srcset');
68-
expect(imageLoaderCompClass).toContain('sn-image-loaded');
69-
expect(imgSrc).toEqual('http://via.placeholder.com/400x400?text=xs+1x 1x, http://via.placeholder.com/800x800?text=xs+2x 2x');
59+
let resultLoaded = page.isImageBottomLoaded();
60+
let expectedLoaded = false;
61+
let resultSrc = page.getImageBottomElementSrc();
62+
let expectedSrc = image.placeholder;
63+
expect(resultLoaded).toEqual(expectedLoaded);
64+
expect(resultSrc).toEqual(expectedSrc);
65+
66+
page.scrollToImageBottomElement();
67+
68+
resultLoaded = page.isImageBottomLoaded();
69+
expectedLoaded = true;
70+
resultSrc = page.getImageBottomElementSrc();
71+
expectedSrc = image.images[0].x1;
72+
expect(resultLoaded).toEqual(expectedLoaded);
73+
expect(resultSrc).toEqual(expectedSrc);
7074

7175
});
7276

73-
it('should update full res image event count scroll into viewport', () => {
74-
expect(page.getBottomFullResCountElement().getText()).toEqual('0');
75-
76-
page.scrollTo(0, 580 * 2);
77-
browser.wait(() => page.getLoadedImageBottomElement());
78-
expect(page.getBottomFullResCountElement().getText()).toEqual('1');
77+
it('should update image loaded count element when image scrolled into viewport', () => {
78+
expect(page.getImageBottomLoadedCountElementText()).toEqual('0');
79+
page.scrollToImageBottomElement();
80+
expect(page.getImageBottomLoadedCountElementText()).toEqual('1');
7981
});
8082

8183
});
@@ -84,48 +86,65 @@ describe('ImageLoader Lib E2E Tests', function () {
8486

8587
it('should load correct image for "xs" device size', () => {
8688
page.setWindowSize(400, 580);
87-
page.scrollTo(0, 580 * 2);
88-
page.waitForImageBottomElementLoaded();
89+
page.scrollToImageBottomElement();
90+
91+
const resultLoaded = page.isImageBottomLoaded();
92+
const expectedLoaded = true;
93+
const resultSrcset = page.getImageBottomElementSrcSet();
94+
const expectedSrcset = `${image.images[0].x1} 1x, ${image.images[0].x2} 2x`;
8995

90-
expect(page.getLoadedImageBottomElement()).toBeTruthy();
91-
expect(page.getImageBottomElementSrcSet()).toEqual(`${image.images[0].x1} 1x, ${image.images[0].x2} 2x`);
96+
expect(resultLoaded).toEqual(expectedLoaded);
97+
expect(resultSrcset).toEqual(expectedSrcset);
9298
});
9399

94100
it('should load correct image for "md" device size', () => {
95101
page.setWindowSize(768, 580);
96-
page.scrollTo(0, 580 * 2.5);
97-
page.waitForImageBottomElementLoaded();
102+
page.scrollToImageBottomElement();
98103

99-
expect(page.getLoadedImageBottomElement()).toBeTruthy();
100-
expect(page.getImageBottomElementSrcSet()).toEqual(`${image.images[1].x1} 1x, ${image.images[1].x2} 2x`);
104+
const resultLoaded = page.isImageBottomLoaded();
105+
const expectedLoaded = true;
106+
const resultSrcset = page.getImageBottomElementSrcSet();
107+
const expectedSrcset = `${image.images[1].x1} 1x, ${image.images[1].x2} 2x`;
108+
109+
expect(resultLoaded).toEqual(expectedLoaded);
110+
expect(resultSrcset).toEqual(expectedSrcset);
101111
});
102112

103113
it('should load correct image for "lg" device size', () => {
104114
page.setWindowSize(1024, 580);
105-
page.scrollTo(0, 580 * 2.5);
106-
page.waitForImageBottomElementLoaded();
115+
page.scrollToImageBottomElement();
116+
117+
const resultLoaded = page.isImageBottomLoaded();
118+
const expectedLoaded = true;
119+
const resultSrcset = page.getImageBottomElementSrcSet();
120+
const expectedSrcset = `${image.images[2].x1} 1x, ${image.images[2].x2} 2x`;
107121

108-
expect(page.getLoadedImageBottomElement()).toBeTruthy();
109-
expect(page.getImageBottomElementSrcSet()).toEqual(`${image.images[2].x1} 1x, ${image.images[2].x2} 2x`);
122+
expect(resultLoaded).toEqual(expectedLoaded);
123+
expect(resultSrcset).toEqual(expectedSrcset);
110124
});
111125

112126
it('should update image loaded event count on window resize when image in viewport', () => {
113-
expect(page.getBottomFullResCountElement().getText()).toEqual('0');
127+
let result = page.getImageBottomLoadedCountElementText();
128+
let expected = '0';
129+
expect(result).toEqual(expected);
114130

115131
page.setWindowSize(400, 580);
116-
page.scrollTo(0, 580 * 2.5);
117-
page.waitForImageBottomElementLoaded();
118-
expect(page.getBottomFullResCountElement().getText()).toEqual('1');
132+
page.scrollToImageBottomElement();
133+
result = page.getImageBottomLoadedCountElementText();
134+
expected = '1';
135+
expect(result).toEqual(expected);
119136

120137
page.setWindowSize(768, 580);
121-
page.scrollTo(0, 580 * 3);
122-
page.waitForImageBottomElementLoaded();
123-
expect(page.getBottomFullResCountElement().getText()).toEqual('2');
138+
page.scrollToImageBottomElement();
139+
result = page.getImageBottomLoadedCountElementText();
140+
expected = '2';
141+
expect(result).toEqual(expected);
124142

125143
page.setWindowSize(1024, 580);
126-
page.scrollTo(0, 580 * 3);
127-
page.waitForImageBottomElementLoaded();
128-
expect(page.getBottomFullResCountElement().getText()).toEqual('3');
144+
page.scrollToImageBottomElement();
145+
result = page.getImageBottomLoadedCountElementText();
146+
expected = '3';
147+
expect(result).toEqual(expected);
129148
});
130149

131150
});

e2e/video-loader.e2e-spec.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import { video } from '../src/app/app-data';
55
describe('VideoLoader Lib E2E Tests', function () {
66
let page: AppPage;
77

8-
const browserWaitTimeout = 10000;
9-
108
beforeEach(() => {
119
page = new AppPage();
1210
page.navigateTo();
@@ -38,8 +36,7 @@ describe('VideoLoader Lib E2E Tests', function () {
3836
it('should load video when in viewport', () => {
3937
expect(page.isVideoLoaded()).toBeFalsy();
4038

41-
page.scrollToBottom();
42-
page.waitForVideoLoaded();
39+
page.scrollToVideoElement();
4340

4441
expect(page.isVideoLoaded()).toBeTruthy();
4542
expect(page.getVideoSrc()).toEqual(video.videos[0].url);
@@ -51,26 +48,23 @@ describe('VideoLoader Lib E2E Tests', function () {
5148

5249
it('should load correct video for "xs" device size', () => {
5350
page.setWindowSize(400, 580);
54-
page.scrollToBottom();
55-
page.waitForVideoLoaded();
51+
page.scrollToVideoElement();
5652

5753
expect(page.isVideoLoaded()).toBeTruthy();
5854
expect(page.getVideoSrc()).toEqual(video.videos[0].url);
5955
});
6056

6157
it('should load correct video for "md" device size', () => {
6258
page.setWindowSize(768, 580);
63-
page.scrollToBottom();
64-
page.waitForVideoLoaded();
59+
page.scrollToVideoElement();
6560

6661
expect(page.isVideoLoaded()).toBeTruthy();
6762
expect(page.getVideoSrc()).toEqual(video.videos[1].url);
6863
});
6964

7065
it('should load correct video for "lg" device size', () => {
7166
page.setWindowSize(1024, 580);
72-
page.scrollToBottom();
73-
page.waitForVideoLoaded();
67+
page.scrollToVideoElement();
7468

7569
expect(page.isVideoLoaded()).toBeTruthy();
7670
expect(page.getVideoSrc()).toEqual(video.videos[2].url);

src/app/app.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ <h3>Top image</h3>
88
</sn-image-loader>
99

1010
<h1>Scroll down for bottom image ↓</h1>
11-
<h3>Bottom placeholder loaded: <span class="placeholder-boolean">{{ placeholderLoaded }}</span></h3>
11+
<h3>Bottom placeholder loaded: <span class="placeholder-loaded">{{ placeholderLoaded }}</span></h3>
1212
<div class="spacer"></div>
1313

1414
<h3>Bottom image</h3>
@@ -21,7 +21,7 @@ <h3>Bottom image</h3>
2121
(imageLoaded)="onImageLoad($event)"
2222
class="sn-image-loader sn-image-loader--bottom">
2323
</sn-image-loader>
24-
<h3>Bottom image imageLoaded event count: <span class="full-res-count">{{ imageLoadedEventCount }}</span></h3>
24+
<h3>Bottom image imageLoaded event count: <span class="image-loaded-count">{{ imageLoadedEventCount }}</span></h3>
2525
<div class="spacer"></div>
2626

2727
<sn-video-loader

0 commit comments

Comments
 (0)