Exemplos de monitores sintéticos

Modelos pré-configurados e exemplos de código permitem criar monitores sintéticos em Node.js e TypeScript usando frameworks como Puppeteer, Selenium WebDriver e Mocha. Use essas amostras, disponíveis no repositório do GitHub synthetics-sdk-nodejs, para consultar URLs, executar jornadas do usuário baseadas em navegador, testar endpoints de API ou verificar links quebrados.

Diretrizes para usar amostras e escrever testes personalizados

Antes de implantar uma amostra ou escrever um teste personalizado, revise os seguintes requisitos:

  • Atualize o URL de destino: antes de implantar qualquer exemplo de código, atualize o campo url para apontar para seu endpoint de destino. Não defina esse campo como https://www.google.com.
  • Gerar um Error em caso de falha no teste: se você escrever testes personalizados em vez de usar um modelo, verifique se o teste é aprovado, a menos que um Error seja gerado. Recomendamos usar a biblioteca Assert para que todas as falhas sejam atribuídas à linha de código correta.

Modelos genéricos

Os modelos genéricos são configurados para coletar dados de rastreamento e de registro de solicitações HTTP de saída. A solução usa o módulo auto-instrumentation-node do OpenTelemetry e o logger Winston. Devido à dependência de produtos de código aberto, espere mudanças na estrutura dos dados de rastreamento e de registros. Portanto, os dados de rastreamento e registro coletados devem ser usados apenas para fins de depuração.

Você pode implementar sua própria abordagem para coletar dados de rastreamento e registro de solicitações HTTP de saída. Para conferir um exemplo de abordagem personalizada, consulte a classe SyntheticAutoInstrumentation.

Exemplo genérico do Node.js

O exemplo generic-synthetic-nodejs ilustra como consultar um URL. Este exemplo contém o mesmo código da função padrão mostrada pelo console Google Cloud . Para ver o exemplo completo, na barra de ferramentas dele, selecione o logotipo do GitHub.

const { instantiateAutoInstrumentation, runSyntheticHandler } = require('@google-cloud/synthetics-sdk-api');
// Run instantiateAutoInstrumentation before any other code runs, to get automatic logs and traces
instantiateAutoInstrumentation();
const functions = require('@google-cloud/functions-framework');
const axios = require('axios');
const assert = require('node:assert');

functions.http('SyntheticFunction', runSyntheticHandler(async ({logger, executionId}) => {
  /*
   * This function executes the synthetic code for testing purposes.
   * If the code runs without errors, the synthetic test is considered successful.
   * If an error is thrown during execution, the synthetic test is considered failed.
   */
  logger.info('Making an http request using synthetics, with execution id: ' + executionId);
  const url = 'https://www.google.com/'; // URL to send the request to
  return await assert.doesNotReject(axios.get(url));
}));

Exemplo de TypeScript

O exemplo generic-synthetic-typescript mostra como consultar um URL. Para ver o exemplo completo, na barra de ferramentas dele, selecione o logotipo do GitHub.

import {runSyntheticHandler, instantiateAutoInstrumentation} from '@google-cloud/synthetics-sdk-api'
// Run instantiateAutoInstrumentation before any other code runs, to get automatic logs and traces
instantiateAutoInstrumentation();
import * as ff from '@google-cloud/functions-framework';
import axios from 'axios';
import assert from 'node:assert';
import {Logger} from 'winston';

ff.http('SyntheticFunction', runSyntheticHandler(async ({logger, executionId}: {logger: Logger, executionId: string|undefined}) => {
  /*
   * This function executes the synthetic code for testing purposes.
   * If the code runs without errors, the synthetic test is considered successful.
   * If an error is thrown during execution, the synthetic test is considered failed.
   */
  logger.info('Making an http request using synthetics, with execution id: ' + executionId);
  const url = 'https://www.google.com/'; // URL to send the request to
  return await assert.doesNotReject(axios.get(url));
}));

Modelo do Puppeteer

Se você usa o Puppeteer, comece com o exemplo generic-puppeteer-nodejs.

Configuração necessária do Puppeteer

Para usar o Puppeteer, siga estas etapas:

  1. Inclua .puppeteerrc.cjs no diretório de origem da sua função do Cloud Run:

    const { join } = require('path');
    
    /**
     * @type {import("puppeteer").Configuration}
     */
    module.exports = {
      cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
    };
  2. Adicione o seguinte script ao arquivo package.json da sua função do Cloud Run:

    "scripts": {
         "gcp-build": "node node_modules/puppeteer/install.mjs"
    },
    

Exemplo do Puppeteer

O exemplo generic-puppeteer-nodejs ilustra como usar o Puppeteer com sua função do Cloud Run. Para ver o exemplo completo, na barra de ferramentas dele, selecione o logotipo do GitHub.

const { instantiateAutoInstrumentation, runSyntheticHandler } = require('@google-cloud/synthetics-sdk-api');
// Run instantiateAutoInstrumentation before any other code runs, to get automatic logs and traces
instantiateAutoInstrumentation();
const functions = require('@google-cloud/functions-framework');
const axios = require('axios');
const assert = require('node:assert');
const puppeteer = require('puppeteer');


functions.http('CustomPuppeteerSynthetic', runSyntheticHandler(async ({logger, executionId}) => {
 /*
  * This function executes the synthetic code for testing purposes.
  * If the code runs without errors, the synthetic test is considered successful.
  * If an error is thrown during execution, the synthetic test is considered failed.
  */

 // Launch a headless Chrome browser and open a new page
 const browser = await puppeteer.launch({ headless: 'new', timeout: 0});
 const page = await browser.newPage();

 // Navigate to the target URL
 const result = await page.goto('https://www.example.com', {waitUntil: 'load'});

 // Confirm successful navigation
 await assert.equal(result.status(), 200);

 // Print the page title to the console
 const title = await page.title();
 logger.info(`My Page title: ${title} ` + executionId);

 // Close the browser
 await browser.close();
}));

Modelo do Selenium WebDriver

Se você usa o Selenium WebDriver, comece com o exemplo generic-selenium-nodejs. A amostra, disponível no GitHub, inclui arquivos index.js e package.json.

Para ver o exemplo completo, na barra de ferramentas dele, selecione o logotipo do GitHub.

const {
  instantiateAutoInstrumentation,
  runSyntheticHandler,
} = require('@google-cloud/synthetics-sdk-api');
// Run instantiateAutoInstrumentation before any other code runs, to get automatic logs and traces
instantiateAutoInstrumentation();
const functions = require('@google-cloud/functions-framework');
const assert = require('node:assert');

const { Builder, Browser, By } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');

/*
 * This function executes the synthetic code for testing purposes.
 * If the code runs without errors, the synthetic test is considered successful.
 * If an error is thrown during execution, the synthetic test is considered failed.
 */
functions.http(
  'CustomSeleniumSynthetic',
  runSyntheticHandler(async ({ logger, executionId }) => {
    /*
     * Construct chrome options
     * Note: `setChromeBinaryPath` must be set to '/srv/bin/chromium' when running in
     *   GCF (but will need to be changed if running on local machine).
     */
    const options = new chrome.Options();
    options.setChromeBinaryPath('/srv/bin/chromium');
    options.addArguments('--headless', '--disable-gpu', '--no-sandbox');

    // Launch headless chrome webdriver with options
    const driver = await new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .build();

    // Navigate to the target URL
    await driver.get('https://example.com');

    // Retrieve title and `a` tag of page
    const title = await driver.getTitle();
    const aTag = await driver.findElement(By.css('a')).getText();

    // assert title is as expected and print to console
    await assert.equal(title, 'Example Domain');
    logger.info(`My URL title is: ${title} ` + executionId);

    await driver.quit();
  })
);

Modelo do Mocha

Se você escrever testes que dependem do modelo Mocha, considere se uma sequência de testes deve continuar ou parar quando ocorrer uma falha. Para interromper uma sequência de testes após uma falha, defina a flag bail.

Para um exemplo completo que inclui a implantação de uma API, a gravação de um conjunto de testes Mocha de amostra para os endpoints da API e a configuração do monitor sintético, consulte o blog Google Cloud Tutorial do Synthetic Monitoring.

O exemplo mocha-url-ok ilustra como uma função do Cloud Run pode invocar um pacote de testes do Mocha e fornece um pacote de testes de exemplo. Para ver o exemplo completo, na barra de ferramentas dele, selecione o logotipo do GitHub.


const functions = require('@google-cloud/functions-framework');
const GcmSynthetics = require('@google-cloud/synthetics-sdk-mocha');

/*
 * This is the server template that is required to run a synthetic monitor in
 * Google Cloud Functions.
 */

functions.http('SyntheticMochaSuite', GcmSynthetics.runMochaHandler({
  spec: `${__dirname}/mocha_tests.spec.js`
}));

/*
 * This is the file may be interacted with to author mocha tests. To interact
 * with other GCP products or services, users should add dependencies to the
 * package.json file, and require those dependencies here A few examples:
 *  - @google-cloud/secret-manager:
 *        https://www.npmjs.com/package/@google-cloud/secret-manager
 *  - @google-cloud/spanner: https://www.npmjs.com/package/@google-cloud/spanner
 *  - Supertest: https://www.npmjs.com/package/supertest
 */

const {expect} = require('chai');
const fetch = require('node-fetch');

it('pings my website', async () => {
  const url = 'https://google.com/'; // URL to send the request to
  const externalRes = await fetch(url);
  expect(externalRes.ok).to.be.true;
});

O exemplo broken-links-ok mostra como configurar um verificador de links quebrados. Para esse modelo, especifique apenas os valores do objeto options. Esse objeto especifica o URI a ser testado e os parâmetros do teste.

Se você usa o Puppeteer, conclua as etapas de configuração obrigatória do Puppeteer.

Para ver o exemplo completo, na barra de ferramentas dele, selecione o logotipo do GitHub.


const functions = require('@google-cloud/functions-framework');
const GcmSynthetics = require('@google-cloud/synthetics-sdk-broken-links');

const options = {
  origin_uri: "https://example.com",
  // link_limit: 10,
  // query_selector_all: "a", // https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
  // get_attributes: ['href'], // https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute
  // link_order: "FIRST_N", // "FIRST_N" or "RANDOM"
  // link_timeout_millis: 30000, // timeout per link
  // max_retries: 0, // number of retries per link if it failed for any reason
  // wait_for_selector: '', // https://pptr.dev/api/puppeteer.page.waitforselector
  // per_link_options: {},
    /*
    // example:
      per_link_options: {
        'http://fake-link1': { expected_status_code: "STATUS_CLASS_4XX" },
        'http://fake-link2': { expected_status_code: 304 },
        'http://fake-link3': { link_timeout_millis: 10000 },
        'http://fake-link4': {
          expected_status_code: "STATUS_CLASS_3XX",
          link_timeout_millis: 10,
        },
      },
    */
  // total_synthetic_timeout_millis: 60000 // Timeout set for the entire Synthetic Monitor
  // screenshot_options: { capture_condition: 'FAILING', storage_location: '' }
};

functions.http('BrokenLinkChecker', GcmSynthetics.runBrokenLinksHandler(options));

A seguir