Skip to content

Commit

Permalink
[amp-story-player] ✅ Add e2e tests (#31716)
Browse files Browse the repository at this point in the history
* add player e2e tests

* add navigaiton tests to see if videos are paused / played

* fix tests

* update basic test
  • Loading branch information
Enriqe committed Dec 28, 2020
1 parent fbe8248 commit 06d5584
Show file tree
Hide file tree
Showing 8 changed files with 543 additions and 0 deletions.
51 changes: 51 additions & 0 deletions examples/amp-story/video-one-page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="canonical" href="video-one-page.html">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<title>Single page video story [test]</title>

<script async custom-element="amp-story" src="https://cdn.ampproject.org/v0/amp-story-1.0.js"></script>
<script async custom-element="amp-video" src="https://cdn.ampproject.org/v0/amp-video-0.1.js"></script>

<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<style amp-custom>
.story-num {
display: block;
position: absolute;
left: 30px;
top: 30px;
width: 30px;
text-align: center;
font-family: sans-serif;
background-color: white;
border-radius: 50%;
}
</style>
</head>
<body>
<amp-story standalone
id="story1"
title="Key Highlights of AMP Conf 2018" publisher="The AMP team"
publisher-logo-src="./img/AMP-Brand-White-Icon.svg"
poster-portrait-src="./img/overview.jpg">>

<amp-story-page id="page-1">
<amp-story-grid-layer template="fill">
<amp-video autoplay loop
id="video1"
width="400"
height="750"
poster="img-city1.jpeg#1"
layout="fill">
<source src="./video/stamp.mp4" type="video/mp4">
</amp-video>
</amp-story-grid-layer>
<amp-story-grid-layer template="vertical"><span class="story-num">1</span></amp-story-grid-layer>
</amp-story-page>

</amp-story>
</body>
</html>
51 changes: 51 additions & 0 deletions examples/amp-story/video-one-page2.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="canonical" href="video-one-page.html">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<title>Single page video story [test]</title>

<script async custom-element="amp-story" src="https://cdn.ampproject.org/v0/amp-story-1.0.js"></script>
<script async custom-element="amp-video" src="https://cdn.ampproject.org/v0/amp-video-0.1.js"></script>

<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<style amp-custom>
.story-num {
display: block;
position: absolute;
left: 30px;
top: 30px;
width: 30px;
text-align: center;
font-family: sans-serif;
background-color: white;
border-radius: 50%;
}
</style>
</head>
<body>
<amp-story standalone
id="story2"
title="Key Highlights of AMP Conf 2018" publisher="The AMP team"
publisher-logo-src="./img/AMP-Brand-White-Icon.svg"
poster-portrait-src="./img/overview.jpg">>

<amp-story-page id="page-1">
<amp-story-grid-layer template="fill">
<amp-video autoplay loop
id="video1"
width="400"
height="750"
poster="img-city1.jpeg#1"
layout="fill">
<source src="./video/stamp-animation.mp4" type="video/mp4">
</amp-video>
</amp-story-grid-layer>
<amp-story-grid-layer template="vertical"><span class="story-num">2</span></amp-story-grid-layer>
</amp-story-page>

</amp-story>
</body>
</html>
100 changes: 100 additions & 0 deletions test/e2e/test-amp-story-player-navigation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* Copyright 2020 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

const VIEWPORT = {
HEIGHT: 768,
WIDTH: 1024,
};

/**
* @param {number} ms
* @return {!Promise}
*/
function timeout(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

describes.endtoend(
'story player navigation',
{
testUrl:
'http://localhost:8000/test/fixtures/e2e/amp-story-player/navigation.html',
initialRect: {width: VIEWPORT.WIDTH, height: VIEWPORT.HEIGHT},
environments: ['single'],
},
(env) => {
let player;
let controller;

beforeEach(async () => {
controller = env.controller;

await timeout(500);

player = await controller.findElement(
'amp-story-player.i-amphtml-story-player-loaded'
);
await expect(player);
});

it('first story should be playing video', async () => {
const shadowHost = await controller.findElement(
'div.i-amphtml-story-player-shadow-root-intermediary'
);

await controller.switchToShadowRoot(shadowHost);

const iframe = await controller.findElement('iframe.story-player-iframe');

await controller.switchToShadowRoot(iframe);
await controller.switchToFrame(iframe);

const firstStoryVideo = await controller.findElement('#story1 video');
const isVideoPaused = await controller.getElementProperty(
firstStoryVideo,
'paused'
);

await timeout(500);
await expect(isVideoPaused).to.eql(false);
});

it('navigating to next story pauses the previous one', async () => {
// Navigate to next story.
await controller.click(player);

await timeout(500);

const shadowHost = await controller.findElement(
'div.i-amphtml-story-player-shadow-root-intermediary'
);
await controller.switchToShadowRoot(shadowHost);

const iframe = await controller.findElement('iframe.story-player-iframe');
await controller.switchToShadowRoot(iframe);
await controller.switchToFrame(iframe);

const firstStoryVideo = await controller.findElement('#story1 video');
const isVideoPaused = await controller.getElementProperty(
firstStoryVideo,
'paused'
);

await timeout(500);
await expect(isVideoPaused).to.eql(true);
});
}
);
184 changes: 184 additions & 0 deletions test/e2e/test-amp-story-player-prerender.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/**
* Copyright 2020 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

const VIEWPORT = {
HEIGHT: 768,
WIDTH: 1024,
};

/**
* @param {number} ms
* @return {!Promise}
*/
function timeout(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

describes.endtoend(
'player prerendering',
{
testUrl:
'http://localhost:8000/test/fixtures/e2e/amp-story-player/pre-rendering.html',
initialRect: {width: VIEWPORT.WIDTH, height: VIEWPORT.HEIGHT},
environments: ['single'],
},
(env) => {
let player;
let controller;

beforeEach(async () => {
controller = env.controller;
player = await controller.findElement(
'amp-story-player.i-amphtml-story-player-loaded'
);
await expect(player);
});

it('player builds the iframe when below the fold', async () => {
const shadowHost = await controller.findElement(
'div.i-amphtml-story-player-shadow-root-intermediary'
);

await controller.switchToShadowRoot(shadowHost);

const iframe = await controller.findElement('iframe');

await expect(iframe);
});

it('when player is far from viewport, no stories are loaded in the iframes', async () => {
const shadowHost = await controller.findElement(
'div.i-amphtml-story-player-shadow-root-intermediary'
);

await controller.switchToShadowRoot(shadowHost);

const iframe = await controller.findElement('iframe');
const iframeSrc = await controller.getElementAttribute(iframe, 'src');

await expect(iframeSrc).to.not.exist;
});

it('when player comes close to the viewport, iframe loads first story in prerender', async () => {
const doc = await controller.getDocumentElement();
const playerRect = await controller.getElementRect(player);

await controller./*OK*/ scrollTo(doc, {top: playerRect.top - 1000});

const shadowHost = await controller.findElement(
'div.i-amphtml-story-player-shadow-root-intermediary'
);

await controller.switchToShadowRoot(shadowHost);

const iframe = await controller.findElement('iframe');
const iframeSrc = await controller.getElementAttribute(iframe, 'src');

await expect(iframeSrc).to.eql(
'http://localhost:8000/examples/amp-story/ampconf.html#visibilityState=prerender&origin=http%3A%2F%2Flocalhost%3A8000&showStoryUrlInfo=0&storyPlayer=v0&cap=swipe'
);
});

it('when player comes close to the viewport, only one iframe is loaded', async () => {
const doc = await controller.getDocumentElement();
const playerRect = await controller.getElementRect(player);

await controller./*OK*/ scrollTo(doc, {top: playerRect.top - 1000});

const shadowHost = await controller.findElement(
'div.i-amphtml-story-player-shadow-root-intermediary'
);

await controller.switchToShadowRoot(shadowHost);

const iframes = await controller.findElements('iframe');
const iframeSrc = await controller.getElementAttribute(iframes[1], 'src');

await expect(iframeSrc).to.not.exist;
});

it('when player becomes visible, first story starts playing', async () => {
const doc = await controller.getDocumentElement();
const playerRect = await controller.getElementRect(player);

await controller./*OK*/ scrollTo(doc, {top: playerRect.top});
const shadowHost = await controller.findElement(
'div.i-amphtml-story-player-shadow-root-intermediary'
);

await controller.switchToShadowRoot(shadowHost);

const iframe = await controller.findElement('iframe.story-player-iframe');

await controller.switchToShadowRoot(iframe);
await controller.switchToFrame(iframe);

const storyEl = await controller.findElement(
'amp-story.i-amphtml-story-loaded'
);

await expect(storyEl).to.exist;
});

it('when player becomes visible and first story finishes loading, second story starts preloading', async () => {
const doc = await controller.getDocumentElement();
const playerRect = await controller.getElementRect(player);

await controller./*OK*/ scrollTo(doc, {top: playerRect.top});
const shadowHost = await controller.findElement(
'div.i-amphtml-story-player-shadow-root-intermediary'
);

await controller.switchToShadowRoot(shadowHost);

// Wait for first story iframe to load.
await timeout(5000);

const iframes = await controller.findElements(
'iframe.story-player-iframe'
);
const iframeSrc = await controller.getElementAttribute(iframes[1], 'src');

await expect(iframeSrc).to.eql(
'http://localhost:8000/examples/amp-story/amp-story-animation.html#visibilityState=prerender&origin=http%3A%2F%2Flocalhost%3A8000&showStoryUrlInfo=0&storyPlayer=v0&cap=swipe'
);
});

it('when player becomes visible and first story finishes loading, third story starts preloading', async () => {
const doc = await controller.getDocumentElement();
const playerRect = await controller.getElementRect(player);

await controller./*OK*/ scrollTo(doc, {top: playerRect.top});
const shadowHost = await controller.findElement(
'div.i-amphtml-story-player-shadow-root-intermediary'
);

await controller.switchToShadowRoot(shadowHost);

// Wait for first story iframe to load.
await timeout(5000);

const iframes = await controller.findElements(
'iframe.story-player-iframe'
);
const iframeSrc = await controller.getElementAttribute(iframes[2], 'src');

await expect(iframeSrc).to.eql(
'http://localhost:8000/examples/amp-story/attachment.html#visibilityState=prerender&origin=http%3A%2F%2Flocalhost%3A8000&showStoryUrlInfo=0&storyPlayer=v0&cap=swipe'
);
});
}
);

0 comments on commit 06d5584

Please sign in to comment.