Google chrome extension 使用木偶机检测和测试铬延伸

Google chrome extension 使用木偶机检测和测试铬延伸,google-chrome-extension,automated-tests,puppeteer,Google Chrome Extension,Automated Tests,Puppeteer,有没有一种方法可以使用Puppeter测试Chrome扩展?例如,扩展能否检测到Chrome是在“测试”模式下启动的,以提供不同的UI、检查内容脚本是否正常工作等?在puppeter中传递--user agent。launch()是一种使用自定义值覆盖浏览器UA的有用方法。然后,您的扩展可以读回背景页面中的navigator.userAgent,并确定Chrome是由Puppeter启动的。此时,您可以提供不同的代码路径来测试crx和正常操作 puppeter_script.js const p

有没有一种方法可以使用Puppeter测试Chrome扩展?例如,扩展能否检测到Chrome是在“测试”模式下启动的,以提供不同的UI、检查内容脚本是否正常工作等?

puppeter中传递
--user agent
。launch()
是一种使用自定义值覆盖浏览器UA的有用方法。然后,您的扩展可以读回背景页面中的
navigator.userAgent
,并确定Chrome是由Puppeter启动的。此时,您可以提供不同的代码路径来测试crx和正常操作

puppeter_script.js

const puppeteer = require('puppeteer');

const CRX_PATH = '/path/to/crx/folder/';

puppeteer.launch({
  headless: false, // extensions only supported in full chrome.
  args: [
    `--disable-extensions-except=${CRX_PATH}`,
    `--load-extension=${CRX_PATH}`,
    '--user-agent=PuppeteerAgent'
  ]
}).then(async browser => {
  // ... do some testing ...
  await browser.close();
});
chrome.runtime.onInstalled.addListener(details => {
  console.log(navigator.userAgent); // "PuppeteerAgent"
});
let LAUNCHED_BY_PUPPETEER = false; // reuse in other parts of your crx as needed.

chrome.tabs.onUpdated.addListener((tabId, info, tab) => {
  if (!LAUNCHED_BY_PUPPETEER && tab.title.includes('PuppeteerAgent')) {
    chrome.tabs.remove(tabId);
    LAUNCHED_BY_PUPPETEER = true;
  }
});
const puppeteer = require('puppeteer');

const CRX_PATH = '/path/to/crx/folder/';

puppeteer.launch({
  headless: false, // extensions only supported in full chrome.
  args: [
    `--disable-extensions-except=${CRX_PATH}`,
    `--load-extension=${CRX_PATH}`,
  ]
}).then(async browser => {
  const page = await browser.newPage();
  await page.evaluate("document.title = 'PuppeteerAgent'");

  // ... do some testing ...

  await browser.close();
});
扩展名background.js

const puppeteer = require('puppeteer');

const CRX_PATH = '/path/to/crx/folder/';

puppeteer.launch({
  headless: false, // extensions only supported in full chrome.
  args: [
    `--disable-extensions-except=${CRX_PATH}`,
    `--load-extension=${CRX_PATH}`,
    '--user-agent=PuppeteerAgent'
  ]
}).then(async browser => {
  // ... do some testing ...
  await browser.close();
});
chrome.runtime.onInstalled.addListener(details => {
  console.log(navigator.userAgent); // "PuppeteerAgent"
});
let LAUNCHED_BY_PUPPETEER = false; // reuse in other parts of your crx as needed.

chrome.tabs.onUpdated.addListener((tabId, info, tab) => {
  if (!LAUNCHED_BY_PUPPETEER && tab.title.includes('PuppeteerAgent')) {
    chrome.tabs.remove(tabId);
    LAUNCHED_BY_PUPPETEER = true;
  }
});
const puppeteer = require('puppeteer');

const CRX_PATH = '/path/to/crx/folder/';

puppeteer.launch({
  headless: false, // extensions only supported in full chrome.
  args: [
    `--disable-extensions-except=${CRX_PATH}`,
    `--load-extension=${CRX_PATH}`,
  ]
}).then(async browser => {
  const page = await browser.newPage();
  await page.evaluate("document.title = 'PuppeteerAgent'");

  // ... do some testing ...

  await browser.close();
});

或者,如果您想保留浏览器的原始UA字符串,那么它会变得很棘手

  • 启动Chrome并在Puppeter中创建一个空白页面
  • 将其标题设置为自定义名称
  • 在后台脚本中检测选项卡的标题更新
  • 设置一个全局标志以便以后重用
  • background.js

    const puppeteer = require('puppeteer');
    
    const CRX_PATH = '/path/to/crx/folder/';
    
    puppeteer.launch({
      headless: false, // extensions only supported in full chrome.
      args: [
        `--disable-extensions-except=${CRX_PATH}`,
        `--load-extension=${CRX_PATH}`,
        '--user-agent=PuppeteerAgent'
      ]
    }).then(async browser => {
      // ... do some testing ...
      await browser.close();
    });
    
    chrome.runtime.onInstalled.addListener(details => {
      console.log(navigator.userAgent); // "PuppeteerAgent"
    });
    
    let LAUNCHED_BY_PUPPETEER = false; // reuse in other parts of your crx as needed.
    
    chrome.tabs.onUpdated.addListener((tabId, info, tab) => {
      if (!LAUNCHED_BY_PUPPETEER && tab.title.includes('PuppeteerAgent')) {
        chrome.tabs.remove(tabId);
        LAUNCHED_BY_PUPPETEER = true;
      }
    });
    
    const puppeteer = require('puppeteer');
    
    const CRX_PATH = '/path/to/crx/folder/';
    
    puppeteer.launch({
      headless: false, // extensions only supported in full chrome.
      args: [
        `--disable-extensions-except=${CRX_PATH}`,
        `--load-extension=${CRX_PATH}`,
      ]
    }).then(async browser => {
      const page = await browser.newPage();
      await page.evaluate("document.title = 'PuppeteerAgent'");
    
      // ... do some testing ...
    
      await browser.close();
    });
    
    puppeter_script.js

    const puppeteer = require('puppeteer');
    
    const CRX_PATH = '/path/to/crx/folder/';
    
    puppeteer.launch({
      headless: false, // extensions only supported in full chrome.
      args: [
        `--disable-extensions-except=${CRX_PATH}`,
        `--load-extension=${CRX_PATH}`,
        '--user-agent=PuppeteerAgent'
      ]
    }).then(async browser => {
      // ... do some testing ...
      await browser.close();
    });
    
    chrome.runtime.onInstalled.addListener(details => {
      console.log(navigator.userAgent); // "PuppeteerAgent"
    });
    
    let LAUNCHED_BY_PUPPETEER = false; // reuse in other parts of your crx as needed.
    
    chrome.tabs.onUpdated.addListener((tabId, info, tab) => {
      if (!LAUNCHED_BY_PUPPETEER && tab.title.includes('PuppeteerAgent')) {
        chrome.tabs.remove(tabId);
        LAUNCHED_BY_PUPPETEER = true;
      }
    });
    
    const puppeteer = require('puppeteer');
    
    const CRX_PATH = '/path/to/crx/folder/';
    
    puppeteer.launch({
      headless: false, // extensions only supported in full chrome.
      args: [
        `--disable-extensions-except=${CRX_PATH}`,
        `--load-extension=${CRX_PATH}`,
      ]
    }).then(async browser => {
      const page = await browser.newPage();
      await page.evaluate("document.title = 'PuppeteerAgent'");
    
      // ... do some testing ...
    
      await browser.close();
    });
    
    注意:缺点是这种方法需要manifest.json中的“tabs”权限


    测试扩展页 假设您想测试弹出页面UI?一种方法是直接导航到它的
    chrome扩展名://
    URL,然后使用puppeter进行UI测试:

    // Can we navigate to a chrome-extension page? YES!
    const page = await browser.newPage();
    await page.goto('chrome-extension://ipfiboohojhbonenbbppflmpfkakjhed/popup.html');
    // click buttons, test UI elements, etc.
    

    要为测试创建一个稳定的扩展id,请检查:

    我错误地认为CRX_路径指向要加载的扩展的.CRX存档,但它是
    manifest.json
    所在的文件夹。还要注意,导航到
    chrome扩展名://
    URL只能在添加了
    --禁用扩展名,但
    --加载扩展名
    参数后才能进行,如本回答中所述。如果您只想单击扩展名按钮,该怎么办?从上述回答和注释中,这一点最初并不清楚(即使它们确实说明了这一点)但您不需要为正在使用的本地扩展名创建CRX文件。相反,您可以将CRX_路径指向您正在使用的文件夹,就像@ericmayerus建议的那样。这意味着使用load Unpacket方法将同一文件夹侧向加载到Chrome中。所以对我来说,我最终添加了
    constcrx_PATH='/Users/alex/git/imdb age'到我的setup.js文件。