

# Gravar um script de canário Node.js usando o runtime do Playwright
<a name="Synthetics_WritingCanary_Nodejs_Playwright"></a>

**Topics**
+ [Empacotar arquivos de canário Node.js para o runtime do Playwright](#Synthetics_canary_Nodejs_Playwright_package)
+ [Alterar um script existente do Playwright para ser usado como um canário do Synthetics](#CloudWatch_Synthetics_canary_edit_Playwright_script)
+ [Configurações do CloudWatch Synthetics](#Synthetics_canary_configure_Playwright_script)

## Empacotar arquivos de canário Node.js para o runtime do Playwright
<a name="Synthetics_canary_Nodejs_Playwright_package"></a>

 O script do canário compreende um arquivo `.js` (sintaxe CommonJS) ou `.mjs` (sintaxe ES) contendo o código do manipulador do Synthetics, em conjunto com quaisquer pacotes e módulos adicionais dos quais o código dependa. Os scripts criados no formato ES (ECMAScript) devem usar .mjs como extensão ou incluir um arquivo package.json com o conjunto de campos “type”: “module”. Ao contrário de outros runtimes, como o Node.js Puppeteer, você não precisa salvar os scripts em uma estrutura de pastas específica. Você pode empacotar os scripts diretamente. Use seu utilitário `zip` preferencial para criar um arquivo `.zip` com o arquivo manipulador na raiz. Se o script do canário depender de pacotes ou módulos adicionais que não estejam inclusos no runtime do Synthetics, é possível adicionar essas dependências ao arquivo `.zip`. Para fazer isso, você pode instalar as bibliotecas necessárias para a função no diretório `node_modules` executando o comando `npm install`. Os comandos de exemplo da CLI a seguir criam um arquivo `.zip` denominado `my_deployment_package.zip` contendo o arquivo `index.js` ou `index.mjs` (manipulador do Synthetics) e suas dependências. No exemplo, você instala as dependências usando o manipulador de pacotes `npm`.

```
~/my_function
├── index.mjs
├── synthetics.json
├── myhelper-util.mjs    
└── node_modules
    ├── mydependency
```

Crie um arquivo `.zip` que contenha o conteúdo da pasta do seu projeto na raiz. Use a opção `r` (recursiva), conforme mostrado no exemplo a seguir, para garantir que `zip` compacte as subpastas.

```
zip -r my_deployment_package.zip .
```

Adicione um arquivo de configuração do Synthetics para configurar o comportamento do CloudWatch Synthetics. Você pode criar um arquivo `synthetics.json` e salvá-lo no mesmo caminho do seu ponto de entrada ou arquivo manipulador.

Opcionalmente, você também pode armazenar o arquivo de ponto de entrada em uma estrutura de pastas de sua escolha. No entanto, certifique-se de que o caminho da pasta esteja especificado no nome do manipulador.

 **Nome do manipulador** 

Defina o ponto de entrada do script do canário (manipulador) como ` myCanaryFilename.functionName` para corresponder ao nome do arquivo do ponto de entrada do script. Opcionalmente, você também pode armazenar o canário em uma pasta separada, como ` myFolder/my_canary_filename.mjs`. Se você armazenar em uma pasta separada, especifique esse caminho no ponto de entrada do script, como ` myFolder/my_canary_filename.functionName`.

## Alterar um script existente do Playwright para ser usado como um canário do Synthetics
<a name="CloudWatch_Synthetics_canary_edit_Playwright_script"></a>

Você pode editar um script existente do Node.js e Playwright para ser usado como canário. Para obter mais informações sobre o Playwright, consulte a documentação da [biblioteca do Playwright](https://playwright.dev/docs/api/class-playwright). 

Você pode usar o script do Playwright a seguir, que está salvo no arquivo ` exampleCanary.mjs`.

```
import { chromium } from 'playwright';
import { expect } from '@playwright/test';

const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com', {timeout: 30000});
await page.screenshot({path: 'example-home.png'});

const title = await page.title();
expect(title).toEqual("Example Domain");
 
await browser.close();
```

Converta o script executando as seguintes etapas:

1. Crie e exporte uma função `handler`. O manipulador é a função de ponto de entrada para o script. Você pode escolher qualquer nome para a função do manipulador, mas a função usada no script deve ser a mesma do manipulador do canário. Se o nome do script for `exampleCanary.mjs`, e o nome da função do manipulador for `myhandler`, o manipulador do canário será denominado `exampleCanary.myhandler`. No exemplo a seguir, o nome da função do manipulador é `handler`.

   ```
   exports.handler = async () => {
     // Your script here
     };
   ```

1. Importe o `Synthetics Playwright module` como uma dependência.

   ```
   import { synthetics } from '@aws/synthetics-playwright';
   ```

1. Inicie um navegador usando a função `Launch` do Synthetics.

   ```
   const browser = await synthetics.launch();
   ```

1. Crie uma página do Playwright usando a função `newPage` do Synthetics.

   ```
   const page = await synthetics.newPage();
   ```

O script agora está pronto para ser executado como um canário do Synthetics. Veja abaixo o script atualizado:

 **Atualizado o script no formato ES6** 

O arquivo de script salvo com uma extensão `.mjs`.

```
import { synthetics } from '@aws/synthetics-playwright';
import { expect } from '@playwright/test';

export const handler = async (event, context) => {
  try {
        // Launch a browser
        const browser = await synthetics.launch();
        
        // Create a new page
        const page = await synthetics.newPage(browser);
        
        // Navigate to a website
        await page.goto('https://www.example.com', {timeout: 30000});
        
        // Take screenshot
        await page.screenshot({ path: '/tmp/example.png' });
        
        // Verify the page title
        const title = await page.title();
        expect(title).toEqual("Example Domain");
    } finally {
        // Ensure browser is closed
        await synthetics.close();
    }
};
```

 **Script atualizado no formato CommonJS** 

O arquivo de script salvo com uma extensão `.js`.

```
const { synthetics } = require('@aws/synthetics-playwright');
const { expect } = require('@playwright/test');

exports.handler = async (event) => {
  try {
    const browser = await synthetics.launch();
    const page = await synthetics.newPage(browser);
    await page.goto('https://www.example.com', {timeout: 30000});
    await page.screenshot({ path: '/tmp/example.png' });
    const title = await page.title();
    expect(title).toEqual("Example Domain");
  } finally {
    await synthetics.close();
  }
};
```

## Configurações do CloudWatch Synthetics
<a name="Synthetics_canary_configure_Playwright_script"></a>

Você pode configurar o comportamento do runtime do Synthetics Playwright fornecendo um arquivo de configuração JSON opcional denominado `synthetics.json`. Esse arquivo deve ser empacotado no mesmo local do arquivo do manipulador. Embora um arquivo de configuração seja opcional, se você não fornecer um arquivo de configuração, ou se não houver uma chave de configuração, o CloudWatch assumirá os padrões.

 **Empacotar o arquivo de configuração** 

Veja abaixo os valores de configuração compatíveis e seus padrões.

```
{
    "step": {
        "screenshotOnStepStart": false,
        "screenshotOnStepSuccess": false,
        "screenshotOnStepFailure": false,
        "stepSuccessMetric": true,
        "stepDurationMetric": true,
        "continueOnStepFailure": true,
        "stepsReport": true
    },
    "report": {
        "includeRequestHeaders": true,
        "includeResponseHeaders": true,
        "includeUrlPassword": false,
        "includeRequestBody": true,
        "includeResponseBody": true,
        "restrictedHeaders": ['x-amz-security-token', 'Authorization'], // Value of these headers is redacted from logs and reports
        "restrictedUrlParameters": ['Session', 'SigninToken'] // Values of these url parameters are redacted from logs and reports
    },
    "logging": {
        "logRequest": false,
        "logResponse": false,
        "logResponseBody": false,
        "logRequestBody": false,
        "logRequestHeaders": false,
        "logResponseHeaders": false
    },
    "httpMetrics": {
        "metric_2xx": true,
        "metric_4xx": true,
        "metric_5xx": true,
        "failedRequestsMetric": true,
        "aggregatedFailedRequestsMetric": true,
        "aggregated2xxMetric": true,
        "aggregated4xxMetric": true,
        "aggregated5xxMetric": true
    },
    "canaryMetrics": {
        "failedCanaryMetric": true,
        "aggregatedFailedCanaryMetric": true
    },
    "userAgent": "",
    "har": true
}
```

 **Configurações das etapas** 
+ `screenshotOnStepStart`: determina se o Synthetics deve obter uma captura de tela antes do início da etapa. O padrão é `true`. 
+ `screenshotOnStepSuccess`: determina se o Synthetics deve obter uma captura de tela após a conclusão de uma etapa. O padrão é `true`. 
+ `screenshotOnStepFailure`: determina se o Synthetics deve obter uma captura de tela após uma etapa falhar. O padrão é `true`. 
+ `continueOnStepFailure`: determina se um script deve continuar mesmo após uma etapa falhar. O padrão é `false`. 
+ `stepSuccessMetric`: determina se a métrica ` SuccessPercent` de uma etapa é emitida. A métrica `SuccessPercent` de uma etapa será `100` para a execução do canário se a etapa tiver êxito, e `0` se a etapa falhar. O padrão é `true`. 
+ `stepDurationMetric`: determina se a métrica `Duration` de uma etapa é emitida. A métrica `Duration` é emitida como a duração, em milissegundos, da execução da etapa. O padrão é `true`.

 **Configurações de relatórios** 

Inclui todos os relatórios gerados pelo CloudWatch Synthetics, como um arquivo HAR e um relatório de etapas do Synthetics. Os campos `restrictedHeaders` e `restrictedUrlParameters` de ocultação de dados sigilosos também se aplicam aos logs gerados pelo Synthetics. 
+ `includeRequestHeaders`: se deve incluir ou não cabeçalhos de solicitação no relatório. O padrão é `false`. 
+ `includeResponseHeaders`: se deve incluir ou não cabeçalhos de resposta no relatório. O padrão é `false`.
+ `includeUrlPassword`: se deve ou não incluir uma senha que apareça no URL. Por padrão, as senhas que aparecem em URLs são ocultadas de logs e relatórios, para evitar a divulgação de dados sigilosos. O padrão é `false` . 
+ `includeRequestBody`: se deve incluir ou não o corpo da solicitação no relatório. O padrão é `false`. 
+ `includeResponseBody`: se deve incluir ou não o corpo da resposta no relatório. O padrão é `false`. 
+ `restrictedHeaders`: uma lista de valores de cabeçalho a serem ignorados, se os cabeçalhos forem incluídos. Isso se aplica aos cabeçalhos de solicitação e de resposta. Por exemplo, você pode ocultar suas credenciais passando `includeRequestHeaders` como true e `restrictedHeaders` como `['Authorization']`. 
+ `restrictedUrlParameters`: uma lista de parâmetros de consulta ou caminho de URL a serem ocultados. Aplica-se a URLs que aparecem em logs, relatórios e erros. O parâmetro faz distinção entre maiúsculas e minúsculas. É possível passar um asterisco (`*`) como um valor para ocultar todos os valores de parâmetros de consulta e caminho de URL. O padrão é uma matriz vazia. 
+ `har`: determina se um arquivo HTTP (HAR) deve ser gerado. O padrão é `true`.

Veja abaixo um exemplo de um arquivo de configurações de relatório.

```
"includeRequestHeaders": true,
"includeResponseHeaders": true,
"includeUrlPassword": false,
"includeRequestBody": true,
"includeResponseBody": true,
"restrictedHeaders": ['x-amz-security-token', 'Authorization'], // Value of these headers is redacted from logs and reports
"restrictedUrlParameters": ['Session', 'SigninToken'] // Values of these URL parameters are redacted from logs and reports
```

 **Configurações de registros em log** 

Aplica-se aos logs gerados pelo CloudWatch Synthetics. Controla o detalhamento dos logs de solicitações e respostas.
+ `logRequest`: se cada solicitação em logs do canário será registrada ou não. Para canaries de interface do usuário, isso registra cada solicitação enviada pelo navegador. O padrão é ` false`. 
+ `logResponse`: se cada resposta em logs do canário será registrada ou não. Para canaries de interface do usuário, registra todas as respostas recebidas pelo navegador. O padrão é ` false`. 
+ `logRequestBody`: se os corpos da solicitação serão registrados ou não junto com as solicitações em logs do canário. Essa configuração se aplicará somente se `logRequest` for true. O padrão é `false`. 
+ `logResponseBody`: se os corpos da resposta serão registrados ou não junto com as solicitações em logs do canário. Essa configuração se aplicará somente se `logResponse` for true. O padrão é `false`. 
+ `logRequestHeaders`: se os cabeçalhos da solicitação serão registrados ou não junto com as solicitações em logs do canário. Essa configuração se aplicará somente se ` logRequest` for true. O padrão é `false`. 
+ `logResponseHeaders`: se os cabeçalhos da resposta serão registrados ou não junto com as respostas em logs do canário. Essa configuração se aplicará somente se ` logResponse` for true. O padrão é `false`. 

 **Configurações de métricas HTTP** 

Configurações de métricas relacionadas à contagem de solicitações de rede com diferentes códigos de status HTTP, emitidos pelo CloudWatch Synthetics para o canário.
+ `metric_2xx`: se deve ou não emitir a métrica `2xx` (com a dimensão `CanaryName`) para o canário. O padrão é ` true`. 
+ `metric_4xx`: se deve ou não emitir a métrica `4xx` (com a dimensão `CanaryName`) para o canário. O padrão é ` true`. 
+ `metric_5xx`: se deve ou não emitir a métrica `5xx` (com a dimensão `CanaryName`) para o canário. O padrão é ` true`. 
+ `failedRequestsMetric`: se deve ou não emitir a métrica ` failedRequests` (com a dimensão `CanaryName`) para o canário. O padrão é `true`. 
+ `aggregatedFailedRequestsMetric`: se deve ou não emitir a métrica ` failedRequests` (sem a dimensão `CanaryName`) para o canário. O padrão é `true`. 
+ `aggregated2xxMetric`: se deve ou não emitir a métrica `2xx` (sem a dimensão `CanaryName`) para o canário. O padrão é `true`. 
+ `aggregated4xxMetric`: se deve ou não emitir a métrica `4xx` (sem a dimensão `CanaryName`) para o canário. O padrão é `true`. 
+ `aggregated5xxMetric`: se deve ou não emitir a métrica `5xx` (sem a dimensão `CanaryName`) para o canário. O padrão é `true`. 

 **Configurações de métricas do canário** 

Configurações de outras métricas emitidas pelo CloudWatch Synthetics.
+ `failedCanaryMetric`: se deve ou não emitir a métrica `Failed` (com a dimensão `CanaryName`) para o canário. O padrão é ` true`. 
+ `aggregatedFailedCanaryMetric`: se deve ou não emitir a métrica ` Failed` (sem a dimensão `CanaryName`) para o canário. O padrão é `true`. 

 **Outras configurações** 
+ `userAgent`: uma string para anexar ao agente do usuário. O agente do usuário é uma string incluída no cabeçalho da solicitação que identifica seu navegador nos sites que você visita ao usar o navegador sem cabeçalho. O CloudWatch Synthetics adiciona automaticamente `CloudWatchSynthetics/{{canary-arn}} to the user agent`. A configuração especificada é anexada ao agente de usuário gerado. O valor do agente de usuário padrão a ser anexado é uma string vazia (`""`).

### Variáveis de ambiente do CloudWatch Synthetics
<a name="Synthetics_canary_Nodejs_Playwright_script"></a>

Configure o formato e o nível do registro em log usando variáveis de ambiente.

 **Formato do log** 

O runtime do CloudWatch Synthetics Playwright cria logs do CloudWatch para cada execução de canário. Os logs são gravados no formato JSON para facilitar a consulta. Opcionalmente, você pode alterar o formato do log para `TEXT`.
+ `Environment variable name`: CW\_SYNTHETICS\_LOG\_FORMAT 
+ `Supported values`: JSON, TEXT 
+ `Default`: JSON 

 **Níveis de logs** 

Embora a habilitação do modo `Debug` aumente o detalhamento, ele pode ser útil para solucionar problemas.
+ `Environment variable name`: CW\_SYNTHETICS\_LOG\_LEVEL
+ `Supported values`: TRACE, DEBUG, INFO, WARN, ERROR, FATAL 
+ `Default`: INFO