Skip to content

Commit

Permalink
Add integration for shadow AMP v0.js (#26344)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinkimball authored Feb 12, 2020
1 parent 15e62b8 commit 4ad2a25
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 7 deletions.
8 changes: 6 additions & 2 deletions build-system/externs/amp.extern.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,12 @@ window.AMP.viewport = {};
window.AMP.viewport.getScrollLeft;
window.AMP.viewport.getScrollWidth;
window.AMP.viewport.getWidth;
window.AMP.attachShadowDoc;
window.AMP.attachShadowDocAsStream;

/** @type {function(!HTMLElement, !Document, !string, Object)} */
window.AMP.attachShadowDoc = function(element, document, url, options) {};

/** @type {function(!HTMLElement, !string, Object)} */
window.AMP.attachShadowDocAsStream = function(element, url, options) {};

/** @constructor */
function AmpConfigType() {}
Expand Down
15 changes: 15 additions & 0 deletions test/fixtures/served/shadow.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html amp lang="en">
<head>
<meta charset="utf-8">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<title>Hello, AMPs</title>
<link rel="canonical" href="https://amp.dev/documentation/guides-and-tutorials/start/create/basic_markup/">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<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>
</head>
<body>
<h1>Shadow AMP document</h1>
<amp-img src="https://placekitten.com/640/480" layout="responsive" width="640" height="480"></amp-img>
</body>
</html>
70 changes: 70 additions & 0 deletions test/integration/test-shadow-amp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* 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.
*/
import {BrowserController} from '../../testing/test-helper';

describes.integration(
'AMP shadow v0',
{
amp: false,
body: `
<!-- unminified src for local-tests.js -->
<script async src="/dist/amp-shadow.js"></script>
<!-- minified src for single-pass-tests.js -->
<script async src="/dist/shadow-v0.js"></script>
<div id="host"></div>
<script>
function fetchDocument(url) {
var xhr = new XMLHttpRequest();
return new Promise((resolve, reject) => {
xhr.open('GET', url, true);
xhr.responseType = 'document';
xhr.setRequestHeader('Accept', 'text/html');
xhr.onload = () => resolve(xhr.responseXML);
xhr.send();
});
}
(window.AMP = window.AMP || []).push(() => {
const host = document.getElementById('host');
const testUrl = 'http://localhost:9876/test/fixtures/served/shadow.html';
fetchDocument(testUrl).then(doc => AMP.attachShadowDoc(host, doc, testUrl));
});
</script>
`,
},
env => {
let docController;
let shadowDoc;

beforeEach(async () => {
docController = new BrowserController(env.win);
await docController.waitForShadowRoot('#host', 25000);
shadowDoc = env.win.document.getElementById('host').shadowRoot;
});

it('should attach shadow AMP document', () => {
return expect(shadowDoc.body.innerText).to.include('Shadow AMP document');
});

it('should layout amp-img component in shadow AMP document', async () => {
const shadowDocController = new BrowserController(env.win, shadowDoc);
await shadowDocController.waitForElementLayout('amp-img');
return expect(
shadowDoc.querySelectorAll('amp-img img[src]')
).to.have.length(1);
});
}
);
28 changes: 23 additions & 5 deletions testing/test-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,9 @@ export class RequestBank {
}

export class BrowserController {
constructor(win) {
constructor(win, opt_rootNode) {
this.win_ = win;
this.doc_ = this.win_.document;
this.rootNode_ = opt_rootNode || this.win_.document;
}

wait(duration) {
Expand All @@ -221,13 +221,31 @@ export class BrowserController {
});
}

/**
* @param {string} hostSelector
* @param {number=} timeout
* @return {!Promise}
*/
waitForShadowRoot(hostSelector, timeout = 10000) {
const element = this.rootNode_.querySelector(hostSelector);
if (!element) {
throw new Error(`BrowserController query failed: ${hostSelector}`);
}
return poll(
`"${hostSelector}" to host shadow doc`,
() => !!element.shadowRoot,
/* onError */ undefined,
timeout
);
}

/**
* @param {string} selector
* @param {number=} timeout
* @return {!Promise}
*/
waitForElementBuild(selector, timeout = 5000) {
const elements = this.doc_.querySelectorAll(selector);
const elements = this.rootNode_.querySelectorAll(selector);
if (!elements.length) {
throw new Error(`BrowserController query failed: ${selector}`);
}
Expand All @@ -250,7 +268,7 @@ export class BrowserController {
* @return {!Promise}
*/
waitForElementLayout(selector, timeout = 10000) {
const elements = this.doc_.querySelectorAll(selector);
const elements = this.rootNode_.querySelectorAll(selector);
if (!elements.length) {
throw new Error(`BrowserController query failed: ${selector}`);
}
Expand All @@ -271,7 +289,7 @@ export class BrowserController {
}

click(selector) {
const element = this.doc_.querySelector(selector);
const element = this.rootNode_.querySelector(selector);
if (element) {
element.dispatchEvent(new /*OK*/ CustomEvent('click', {bubbles: true}));
}
Expand Down

0 comments on commit 4ad2a25

Please sign in to comment.