title: Run JavaScript in clean chrome/puppeteer context
body: <p>I am attempting to run JavaScript on a page context with content scraping as the goal. With puppeteer, I can easily call <code>evaluate()</code> and run a piece of JavaScript inside the context of the page. So I basically just evaluate a <code>document.querySelector</code> on the page:</p>
  
  <pre><code>const puppeteer = require('puppeteer');
  const url = 'file:///C:/Users/roel/puppettest/index.html';
  
  puppeteer.launch({headless: false}).then(async browser =&gt; {
      const page = await browser.newPage();
      await page.goto(url, {waitUntil: 'domcontentloaded'});
      const value = await page.evaluate(() =&gt; document.querySelector('div').textContent);
      if (value === 'Hello') {
          console.log('Works');
      } else {
          console.log('Nope :-(');
      }
  });
  </code></pre>
  
  <p>And this is the page that I referred to:</p>
  
  <pre><code>&lt;html&gt;
      &lt;body&gt;
          &lt;div&gt;Hello&lt;/div&gt;
          &lt;script&gt;
              var div = document.createElement('div');
              div.textContent = 'Whooh!';
              document.body.appendChild(div);
              document.querySelector = null;
          &lt;/script&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>So here's the problem: The code I evaluated runs a <code>document.querySelector</code>, but the page that I loaded set that to <code>null</code>. Chaos ensues. So... <strong>I want to ensure that the JavaScript that I run is ran on a clean context</strong>.</p>
  
  <h3>First Idea:</h3>
  
  <p>I can just retrieve the generated HTML and create a new JavaScript context around the DOM. Run a <code>page.content()</code> to retrieve the HTML and... Oh, it's not the current HTML, it's the initial HTML (e.g. the <code>document.createElement()</code> didn't execute). Running a <code>page.evaluate(() =&gt; document.body.innerHTML)</code> would work assuming the page didn't add a <code>Object.defineProperty</code> on <code>body</code> property of <code>document</code>. But there is no such guarantee. Is there a way to retrieve the current HTML without touching the JS context?</p>
  
  <h3>Second Idea:</h3>
  
  <p>Chrome extensions run in their own JavaScript context with access to the DOM, and only the DOM. Which is exactly what I'm after. Looking over the <code>puppeteer</code> documentation, there is no indication to creating such a context within puppeteer itself. Or is there and I missed it?</p>
  
  <p>...</p>
  
  <p>So how do I go about getting a clean JS context to run queries against?</p>
  
  <p><strong>EDIT</strong> I read the output of <code>.content()</code> wrong. The HTML is included. So, the first idea does work. I'm still curious if the second idea is achieveable as it is much preferred.</p>