Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Kode sampel untuk skrip canary
Bagian ini memuat sampel kode yang menggambarkan beberapa kemungkinan fungsi untuk CloudWatch Naskah canary sintetis.
Sampel untuk Node.js dan Penulis Naskah
Dramawan kenari dengan beberapa langkah
Script berikut adalah contoh dari Node.js Playwright canary dengan beberapa langkah.
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(); } }
Penulis naskah kenari mengatur cookie
Skrip berikut adalah contoh dari Node.js Playwright canary yang mengatur tiga cookie.
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(); } };
Sampel untuk Node.js dan Puppeteer
Mengatur cookie
Situs web mengandalkan cookie untuk menyediakan fungsionalitas kustom atau melacak para pengguna. Dengan menyetel cookie dalam skrip CloudWatch Synthetics, Anda dapat meniru perilaku kustom ini dan memvalidasinya.
Misalnya, situs web dapat menampilkan tautan Login untuk pengguna yang mengunjungi kembali, bukan tautan Daftar.
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(); };
Emulasi perangkat
Anda dapat menulis skrip yang mengemulasi berbagai perangkat sehingga Anda dapat memperkirakan cara halaman terlihat dan berfungsi pada perangkat tersebut.
Sampel berikut mengemulasi perangkat iPhone 6. Untuk informasi selengkapnya tentang emulasi, silakan lihat page.emulate(options)
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(); };
Canary API multi-langkah
Kode sampel ini menunjukkan API canary dengan dua langkah HTTP: menguji API yang sama untuk kasus uji positif dan negatif. Konfigurasi langkah diteruskan untuk mengaktifkan pelaporan header permintaan/respons. Selain itu, ia menyembunyikan header Otorisasi dan X-Amz-Security-Token, karena mengandung kredensil pengguna.
Ketika skrip ini digunakan sebagai canary, Anda dapat melihat detail tentang setiap langkah dan permintaan HTTP terkait seperti langkah lulus/gagal, durasi, dan metrik performa seperti waktu pencarian DNS dan waktu byte pertama. Anda dapat melihat jumlah 2xx, 4xx dan 5xx untuk berjalannya canary Anda.
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(); };
Sampel untuk Python dan Selenium
Sampel kode Selenium berikut adalah sebuah canary yang gagal dengan sebuah pesan kesalahan kustom saat sebuah elemen target tidak dimuat.
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()