From b65f16892c25f48187839ca4e7d7207558cc30da Mon Sep 17 00:00:00 2001 From: erwin mombay Date: Thu, 3 Nov 2016 10:46:45 -0700 Subject: [PATCH] Allow for hosted testing to override where third party frame is retrieved from (#5890) * Allow for hosted testing to override where third party frame is retrieved from * test my own site * fix ava tests --- DEVELOPING.md | 6 ++++++ build-system/SERVING.md | 1 + build-system/tasks/prepend-global/index.js | 12 +++++++++--- build-system/tasks/prepend-global/test.js | 8 ++++---- gulpfile.js | 12 ++++++++++++ package.json | 5 ++++- src/3p-frame.js | 8 ++++++-- src/config.js | 9 ++++++--- src/mode.js | 4 ++++ 9 files changed, 52 insertions(+), 13 deletions(-) diff --git a/DEVELOPING.md b/DEVELOPING.md index 7a0adfb4d3fa..4d75bf56220c 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -51,6 +51,7 @@ If you have any questions, feel free to ask on the issue or join us on [Slack](h | `gulp lint --watch` | Watches for changes in files, Validates against Google Closure Linter.| | `gulp lint --fix` | Fixes simple lint warnings/errors automatically. | | `gulp build`[[1]](#footnote-1) | Builds the AMP library. | +| `gulp build --fortesting`[[1]](#footnote-1) | Builds the AMP library and will read the AMP_TESTING_HOST environment variable to write out an override AMP_CONFIG. | | `gulp build --css-only`[[1]](#footnote-1) | Builds only the embedded css into js files for the AMP library. | | `gulp clean` | Removes build output. | | `gulp css` | Recompile css to build directory. | @@ -127,6 +128,11 @@ For deploying and testing local AMP builds on [HEROKU](https://www.heroku.com/) Meantime, you can also use our automatic build on Heroku [link](http://amphtml-nightly.herokuapp.com/), which is normally built with latest head on master branch (please allow delay). The first time load is normally slow due to Heroku's free account throttling policy. +To correctly get ads and third party working when testing on hosted services +you will need set the `AMP_TESTING_HOST` environment variable. (On heroku this +is done through +`heroku config:set AMP_TESTING_HOST=my-heroku-subdomain.herokuapp.com`) + ## Repository Layout
   3p/             - Implementation of third party sandbox iframes.
diff --git a/build-system/SERVING.md b/build-system/SERVING.md
index feba93c37e36..e50e2673f33b 100644
--- a/build-system/SERVING.md
+++ b/build-system/SERVING.md
@@ -52,6 +52,7 @@ rm /path/to/cdn/production/alp.js.bak
 # make sure and prepend the global production config to main binaries
 gulp prepend-global --target /path/to/cdn/production/v0.js --prod
 gulp prepend-global --target /path/to/cdn/production/alp.js --prod
+gulp prepend-global --target /path/to/3p/cdn/production/f.js --prod
 
 # The following commands below are optional if you want to host a similar
 # experiments page like https://cdn.ampproject.org/experiments.html
diff --git a/build-system/tasks/prepend-global/index.js b/build-system/tasks/prepend-global/index.js
index 3e9dd9819c9f..4095305648e9 100644
--- a/build-system/tasks/prepend-global/index.js
+++ b/build-system/tasks/prepend-global/index.js
@@ -42,6 +42,9 @@ function sanityCheck(str) {
  * @return {!Promise}
  */
 function checkoutBranchConfigs(filename, opt_branch) {
+  if (argv.local) {
+    return Promise.resolve();
+  }
   var branch = opt_branch || 'origin/master';
   // One bad path here will fail the whole operation.
   return exec(`git checkout ${branch} ${filename}`)
@@ -61,7 +64,7 @@ function checkoutBranchConfigs(filename, opt_branch) {
  * @return {string}
  */
 function prependConfig(configString, fileString) {
-  return `window.AMP_CONFIG||(window.AMP_CONFIG=${configString});` +
+  return `self.AMP_CONFIG||(self.AMP_CONFIG=${configString});` +
     `/*AMP_CONFIG*/${fileString}`;
 }
 
@@ -93,7 +96,10 @@ function valueOrDefault(value, defaultValue) {
 }
 
 function main() {
-  if (!argv.target) {
+  var TESTING_HOST = process.env.AMP_TESTING_HOST;
+  var target = argv.target || TESTING_HOST;
+
+  if (!target) {
     util.log(util.colors.red('Missing --target.'));
     return;
   }
@@ -105,7 +111,6 @@ function main() {
 
   var globs = [].concat(argv.files).filter(x => typeof x == 'string');
   var branch = argv.branch;
-  var target = argv.target;
   var filename = '';
 
   // Prod by default.
@@ -152,6 +157,7 @@ gulp.task('prepend-global', 'Prepends a json config to a target file', main, {
         'Takes in an optional value for a custom prod config source.',
     'branch': '  Switch to a git branch to get config source from. ' +
         'Uses master by default.',
+    'local': '  Don\'t switch branches and use local config',
   }
 });
 
diff --git a/build-system/tasks/prepend-global/test.js b/build-system/tasks/prepend-global/test.js
index 108b78f75d17..8e2e5936e1a9 100644
--- a/build-system/tasks/prepend-global/test.js
+++ b/build-system/tasks/prepend-global/test.js
@@ -25,7 +25,7 @@ var targetFile = 'target-file.js';
 test('sync - prepends global config', t => {
   t.plan(1);
   var res = m.prependConfig('{"hello":"world"}', 'var x = 1 + 1;');
-  t.is(res, 'window.AMP_CONFIG||(window.AMP_CONFIG={"hello":"world"});' +
+  t.is(res, 'self.AMP_CONFIG||(self.AMP_CONFIG={"hello":"world"});' +
       '/*AMP_CONFIG*/var x = 1 + 1;');
 });
 
@@ -39,13 +39,13 @@ test('sync - valueOrDefault', t => {
 
 test('sync - sanityCheck', t => {
   t.plan(3);
-  var badStr = 'window.AMP_CONFIG||(window.AMP_CONFIG={"hello":"world"})' +
+  var badStr = 'self.AMP_CONFIG||(self.AMP_CONFIG={"hello":"world"})' +
       '/*AMP_CONFIG*/' +
-      'window.AMP_CONFIG||(window.AMP_CONFIG={"hello":"world"})' +
+      'self.AMP_CONFIG||(self.AMP_CONFIG={"hello":"world"})' +
       '/*AMP_CONFIG*/' +
       'var x = 1 + 1;';
   var badStr2 = 'var x = 1 + 1;';
-  var goodStr = 'window.AMP_CONFIG||(window.AMP_CONFIG={"hello":"world"})' +
+  var goodStr = 'self.AMP_CONFIG||(self.AMP_CONFIG={"hello":"world"})' +
       '/*AMP_CONFIG*/' +
       'var x = 1 + 1;';
   t.false(m.sanityCheck(badStr));
diff --git a/gulpfile.js b/gulpfile.js
index 837210b9e4ad..67884e4ea19b 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -343,6 +343,18 @@ function buildExtensionJs(path, name, version, options) {
  * Main Build
  */
 function build() {
+  var TESTING_HOST = process.env.AMP_TESTING_HOST;
+  if (argv.fortesting && typeof TESTING_HOST == 'string') {
+    var AMP_CONFIG = {
+      thirdPartyFrameHost: TESTING_HOST,
+      thirdPartyFrameRegex: TESTING_HOST,
+      localDev: true,
+    };
+    console.log($$.util.colors.green('trying to write AMP_CONFIG.'));
+    fs.writeFileSync('node_modules/AMP_CONFIG.json',
+        JSON.stringify(AMP_CONFIG));
+    console.log($$.util.colors.green('AMP_CONFIG written successfully.'));
+  }
   process.env.NODE_ENV = 'development';
   polyfillsForTests();
   buildAlp();
diff --git a/package.json b/package.json
index d53dcdcdd565..26ce3172caee 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,10 @@
     "lint": "gulp lint",
     "build": "gulp build",
     "dist": "gulp dist",
-    "heroku-postbuild": "gulp clean && gulp build && gulp dist --fortesting"
+    "heroku-postbuild": "npm run test-env-var && gulp clean && gulp build --fortesting && gulp dist --fortesting && npm run prepend-amp && npm run prepend-v0",
+    "test-env-var": "if [ -z \"${AMP_TESTING_HOST}\" ]; then echo \"ERROR: Please set the 'AMP_TESTING_HOST' environment variable. If you are in heroku this can be set by executing 'heroku config:set AMP_TESTING_HOST=my-heroku-subdomain.herokuapp.com' on the command line.\"; exit 1; fi",
+    "prepend-amp": "gulp prepend-global --prod node_modules/AMP_CONFIG.json --local --target dist/amp.js && gulp prepend-global --prod node_modules/AMP_CONFIG.json --local --target dist.3p/current/integration.js",
+    "prepend-v0": "gulp prepend-global --prod node_modules/AMP_CONFIG.json --local --target dist/v0.js && gulp prepend-global --prod node_modules/AMP_CONFIG.json --local --target dist.3p/current-min/f.js"
   },
   "dependencies": {
     "document-register-element": "1.1.1",
diff --git a/src/3p-frame.js b/src/3p-frame.js
index d0ca1c1b35d6..22453e5a8619 100644
--- a/src/3p-frame.js
+++ b/src/3p-frame.js
@@ -220,8 +220,9 @@ function getDefaultBootstrapBaseUrl(parentWindow) {
       return overrideBootstrapBaseUrl;
     }
     return getAdsLocalhost(parentWindow)
-        + '/dist.3p/current'
-        + (getMode().minified ? '-min/frame' : '/frame.max')
+        + '/dist.3p/'
+        + (getMode().minified ? '$internalRuntimeVersion$/frame'
+            : 'current/frame.max')
         + '.html';
   }
   return 'https://' + getSubDomain(parentWindow) +
@@ -229,6 +230,9 @@ function getDefaultBootstrapBaseUrl(parentWindow) {
 }
 
 function getAdsLocalhost(win) {
+  if (urls.localDev) {
+    return `http://${urls.thirdPartyFrameHost}`;
+  }
   return 'http://ads.localhost:'
       + (win.location.port || win.parent.location.port);
 }
diff --git a/src/config.js b/src/config.js
index e24e3a4bbc64..1ce543a68522 100644
--- a/src/config.js
+++ b/src/config.js
@@ -23,13 +23,16 @@
  */
 const env = self.AMP_CONFIG || {};
 
-/** @type {!Object} */
+const thirdPartyFrameRegex = typeof env['thirdPartyFrameRegex'] == 'string' ?
+    new RegExp(env['thirdPartyFrameRegex']) : env['thirdPartyFrameRegex'];
+
+/** @type {!Object} */
 export const urls = {
   thirdParty: env['thirdPartyUrl'] || 'https://3p.ampproject.net',
   thirdPartyFrameHost: env['thirdPartyFrameHost'] || 'ampproject.net',
-  thirdPartyFrameRegex: env['thirdPartyFrameRegex'] ||
-      /^d-\d+\.ampproject\.net$/,
+  thirdPartyFrameRegex: thirdPartyFrameRegex || /^d-\d+\.ampproject\.net$/,
   cdn: env['cdnUrl'] || 'https://cdn.ampproject.org',
   errorReporting: env['errorReportingUrl'] ||
       'https://amp-error-reporting.appspot.com/r',
+  localDev: env['localDev'] || false,
 };
diff --git a/src/mode.js b/src/mode.js
index bb85b4963f4b..5db68f0ef5b3 100644
--- a/src/mode.js
+++ b/src/mode.js
@@ -75,8 +75,12 @@ function getMode_(win) {
   // while IS_DEV is only replaced when the --fortesting flag is NOT used.
   const IS_DEV = true;
   const IS_MINIFIED = false;
+  const FORCE_LOCALDEV = !!(self.AMP_CONFIG && self.AMP_CONFIG.localDev);
+  const AMP_CONFIG_3P_FRAME_HOST = self.AMP_CONFIG &&
+      self.AMP_CONFIG.thirdPartyFrameHost;
 
   const isLocalDev = IS_DEV && !!(win.location.hostname == 'localhost' ||
+      (FORCE_LOCALDEV && win.location.hostname == AMP_CONFIG_3P_FRAME_HOST) ||
       (win.location.ancestorOrigins && win.location.ancestorOrigins[0] &&
         win.location.ancestorOrigins[0].indexOf('http://localhost:') == 0)) &&
       // Filter out localhost running against a prod script.