Exemple de code pour les scripts Canary - Amazon CloudWatch

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Exemple de code pour les scripts Canary

Cette section contient des exemples de code illustrant certaines fonctions possibles pour les scripts CloudWatch Canary de Synthetics.

Exemples pour Node.js et Playwright

Canari dramaturge à plusieurs étapes

Le script suivant est un exemple de canari Playwright de Node.js comportant plusieurs étapes.

import { synthetics } from '@amzn/synthetics-playwright'; export async function handler(event, context) { try { console.log('Running Synthetics Playwright canary'); const browser = await synthetics.launch(); const browserContext = await browser.newContext(); const page = await synthetics.getPage(browserContext); // Add steps // Step 1 await synthetics.executeStep("home-page", async () => { console.log("Verify home page loads") await page.goto('https://www.amazon.com', {waitUntil: "load"}); await new Promise(r => setTimeout(r, 5000)); }); // Step 2 await synthetics.executeStep("search", async () => { console.log("Searching for a product") const searchInput = page.getByPlaceholder("Search Amazon").first(); await searchInput.click() await searchInput.fill('Amazon echo'); const btn = page.getByRole('button', { name: 'Go' }).first() await btn.click({ timeout: 15000 }) console.log("Clicked search button") }); // Step 3 await synthetics.executeStep("search-results", async () => { console.log("Verifying search results") const resultsHeading = page.getByText("Results", {exact: true}).first() await resultsHeading.highlight(); await new Promise(r => setTimeout(r, 5000)); }); } finally { // Close all browser contexts and browser await synthetics.close(); } }

Des canaris dramaturges installent des cookies

Le script suivant est un exemple d'un canari de Node.js Playwright paramétrant trois cookies.

import { synthetics } from '@amzn/synthetics-playwright'; export const handler = async (event, context) => { try { let url = "http://smile.amazon.com/"; const browser = await synthetics.launch(); const page = await synthetics.getPage(browser); const cookies = [{ 'name': 'cookie1', 'value': 'val1', 'url': url }, { 'name': 'cookie2', 'value': 'val2', 'url': url }, { 'name': 'cookie3', 'value': 'val3', 'url': url } ]; await page.context().addCookies(cookies); await page.goto(url, {waitUntil: 'load', timeout: 30000}); await page.screenshot({ path: '/tmp/smile.png' }); } finally { await synthetics.close(); } };

Exemples pour Node.js et Puppeteer

Définition des cookies

Les sites web s'appuient sur des cookies pour fournir des fonctionnalités personnalisées ou suivre les utilisateurs. En configurant des cookies dans CloudWatch les scripts Synthetics, vous pouvez imiter ce comportement personnalisé et le valider.

Par exemple, un site web peut afficher un lien Connexion pour un utilisateur qui a déjà consulté le site au lieu d'un lien S'enregistrer.

var synthetics = require('Synthetics'); const log = require('SyntheticsLogger'); const pageLoadBlueprint = async function () { let url = "http://smile.amazon.com/"; let page = await synthetics.getPage(); // Set cookies. I found that name, value, and either url or domain are required fields. const cookies = [{ 'name': 'cookie1', 'value': 'val1', 'url': url },{ 'name': 'cookie2', 'value': 'val2', 'url': url },{ 'name': 'cookie3', 'value': 'val3', 'url': url }]; await page.setCookie(...cookies); // Navigate to the url await synthetics.executeStep('pageLoaded_home', async function (timeoutInMillis = 30000) { var response = await page.goto(url, {waitUntil: ['load', 'networkidle0'], timeout: timeoutInMillis}); // Log cookies for this page and this url const cookiesSet = await page.cookies(url); log.info("Cookies for url: " + url + " are set to: " + JSON.stringify(cookiesSet)); }); }; exports.handler = async () => { return await pageLoadBlueprint(); };

Émulation d'appareils

Vous pouvez écrire des scripts qui émulent divers appareils pour obtenir un aperçu de l'apparence et du comportement d'une page sur ces appareils.

L'exemple suivant émule un iPhone 6. Pour de plus amples informations sur l'émulation, veuillez consulter page.emulate(options) dans la documentation Puppeteer.

var synthetics = require('Synthetics'); const log = require('SyntheticsLogger'); const puppeteer = require('puppeteer-core'); const pageLoadBlueprint = async function () { const iPhone = puppeteer.devices['iPhone 6']; // INSERT URL here const URL = "https://amazon.com"; let page = await synthetics.getPage(); await page.emulate(iPhone); //You can customize the wait condition here. For instance, //using 'networkidle2' may be less restrictive. const response = await page.goto(URL, {waitUntil: 'domcontentloaded', timeout: 30000}); if (!response) { throw "Failed to load page!"; } await page.waitFor(15000); await synthetics.takeScreenshot('loaded', 'loaded'); //If the response status code is not a 2xx success code if (response.status() < 200 || response.status() > 299) { throw "Failed to load page!"; } }; exports.handler = async () => { return await pageLoadBlueprint(); };

Script Canary d'API à plusieurs étapes

Cet exemple de code illustre un script Canary d'API avec deux étapes HTTP afin de tester la même API pour les cas de tests positifs et négatifs. La configuration des étapes est transmise pour permettre le signalement des request/response en-têtes. En outre, il masque l'en-tête d'autorisation X-Amz-Security-Token, car ils contiennent les informations d'identification de l'utilisateur.

Lorsque ce script est utilisé en tant que script Canary, vous pouvez afficher des détails sur chaque étape et les demandes HTTP associées, tels que la réussite/l'échec de l'étape, la durée et les métriques de performances telles que le temps de recherche DNS et le temps du premier octet. Vous pouvez voir le nombre de 2xx, 4xx et 5xx pour l'exécution de votre script Canary.

var synthetics = require('Synthetics'); const log = require('SyntheticsLogger'); const apiCanaryBlueprint = async function () { // Handle validation for positive scenario const validatePositiveCase = async function(res) { return new Promise((resolve, reject) => { if (res.statusCode < 200 || res.statusCode > 299) { throw res.statusCode + ' ' + res.statusMessage; } let responseBody = ''; res.on('data', (d) => { responseBody += d; }); res.on('end', () => { // Add validation on 'responseBody' here if required. For ex, your status code is 200 but data might be empty resolve(); }); }); }; // Handle validation for negative scenario const validateNegativeCase = async function(res) { return new Promise((resolve, reject) => { if (res.statusCode < 400) { throw res.statusCode + ' ' + res.statusMessage; } resolve(); }); }; let requestOptionsStep1 = { 'hostname': 'myproductsEndpoint.com', 'method': 'GET', 'path': '/test/product/validProductName', 'port': 443, 'protocol': 'https:' }; let headers = {}; headers['User-Agent'] = [synthetics.getCanaryUserAgentString(), headers['User-Agent']].join(' '); requestOptionsStep1['headers'] = headers; // By default headers, post data and response body are not included in the report for security reasons. // Change the configuration at global level or add as step configuration for individual steps let stepConfig = { includeRequestHeaders: true, includeResponseHeaders: true, restrictedHeaders: ['X-Amz-Security-Token', 'Authorization'], // Restricted header values do not appear in report generated. includeRequestBody: true, includeResponseBody: true }; await synthetics.executeHttpStep('Verify GET products API with valid name', requestOptionsStep1, validatePositiveCase, stepConfig); let requestOptionsStep2 = { 'hostname': 'myproductsEndpoint.com', 'method': 'GET', 'path': '/test/canary/InvalidName(', 'port': 443, 'protocol': 'https:' }; headers = {}; headers['User-Agent'] = [synthetics.getCanaryUserAgentString(), headers['User-Agent']].join(' '); requestOptionsStep2['headers'] = headers; // By default headers, post data and response body are not included in the report for security reasons. // Change the configuration at global level or add as step configuration for individual steps stepConfig = { includeRequestHeaders: true, includeResponseHeaders: true, restrictedHeaders: ['X-Amz-Security-Token', 'Authorization'], // Restricted header values do not appear in report generated. includeRequestBody: true, includeResponseBody: true }; await synthetics.executeHttpStep('Verify GET products API with invalid name', requestOptionsStep2, validateNegativeCase, stepConfig); }; exports.handler = async () => { return await apiCanaryBlueprint(); };

Exemples pour Python et Selenium

L'exemple de code Selenium suivant est un script Canary qui échoue avec un message d'erreur personnalisé lorsqu'un élément cible n'est pas chargé.

from aws_synthetics.selenium import synthetics_webdriver as webdriver from aws_synthetics.common import synthetics_logger as logger from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By def custom_selenium_script(): # create a browser instance browser = webdriver.Chrome() browser.get('https://www.example.com/') logger.info('navigated to home page') # set cookie browser.add_cookie({'name': 'foo', 'value': 'bar'}) browser.get('https://www.example.com/') # save screenshot browser.save_screenshot('signed.png') # expected status of an element button_condition = EC.element_to_be_clickable((By.CSS_SELECTOR, '.submit-button')) # add custom error message on failure WebDriverWait(browser, 5).until(button_condition, message='Submit button failed to load').click() logger.info('Submit button loaded successfully') # browser will be quit automatically at the end of canary run, # quit action is not necessary in the canary script browser.quit() # entry point for the canary def handler(event, context): return custom_selenium_script()