[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/node/http.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
const axios = require('axios')

const system = require('./system')

exports.request = async (axiosConfig) => {
  let response

  await axios(axiosConfig)
    .then((result) => {
      response = result
    })
    .catch((e) => {
      system.crash('Request failed', JSON.stringify(e.response.data))
    })

  return response
}

exports.runningSorryCypress = async () => {
  let response
  const axiosConfig = {
    url: 'http://localhost:1234',
    method: 'get',
  }

  await axios(axiosConfig)
    .then((result) => {
      response = result
    })
    .catch((_e) => {
      return false
    })

  return response?.status === 200
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/node/lock.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
const cfg = require('./config')
const logger = require('./logger')
const system = require('./system')
const storage = require('./storage')
const credentials = require('./credentials')
const toolbelt = require('./toolbelt')
const http = require('./http')

const [, , action] = process.argv
const MAX_TIME = 40 // Forced releasing time for stuck workspace (minutes)

async function checkAccount() {
  logger.init()
  logger.msgSection('Cypress Runner - Handle account level resources')
  const config = storage.readYaml('cy-runner.yml')
  const secrets = credentials.readSecrets(config)
  // eslint-disable-next-line global-require,import/no-self-import
  const lock = require('./lock')

  if (action === 'reserve') return lock.reserveAccount(config, secrets)
  if (action === 'release') return lock.releaseAccount(config, secrets)

  system.crash(
    `You must call me with 'reserve' or 'release' action`,
    `./cy-runner/node/lock ( reserve | release )`
  )
}

exports.reserveAccount = async (config, secrets = null) => {
  // If from action, show next section
  if (action) logger.msgSection('Reserve account level resources')

  logger.msgOk(`Checking current configuration`)
  // Check current configuration
  const orderFormCfg = await getOrderFormConfig(config, secrets)

  // Save results to be used later
  config.data = orderFormCfg.data

  // Check
  if (orderFormCfg.startTime) {
    // Yes, get the time running in seconds
    const ranTime = (Date.now() - orderFormCfg.startTime) / 1000 / 60

    if (ranTime < MAX_TIME) {
      // Test running less than 40 minutes, try again later
      logger.msgError('Another test is running', true)
      system.crash(
        `Account ${config.base.vtex.account} was reserved to ${orderFormCfg.workspace}`,
        `Please, try again in ${Math.floor(MAX_TIME - ranTime)} minutes`,
        { pr: true, dump: false }
      )
    } else {
      // Test running more than 40 minutes or appId miss configured
      logger.msgPad(
        `Workspace ${orderFormCfg.workspace} stuck [${Math.floor(
          ranTime
        )} minutes], releasing`
      )
      await this.releaseAccount(config, secrets)
    }
  }

  // Set up base info
  config.workspace.name = await cfg.getWorkspaceName(config)
  const { account } = config.base.vtex

  // Reserve app
  logger.msgOk(`Reserving ${account} to ${config.workspace.name}`)
  config.data.apps.push({
    fields: [config.workspace.name, Date.now()],
    id: 'e2e',
    major: 1,
  })
  await setOrderFormConfig(config, secrets)

  // Set up other reservations
  await setAppConfig(config, secrets)

  // If we reach here, everything is good
  logger.msgOk('Requested successfully')
}

exports.releaseAccount = async (config, secrets = null) => {
  // If from action, show start section
  if (action) logger.msgSection('Release account level resources')

  logger.msgOk('Releasing account level resources')
  const orderFormCfg = await getOrderFormConfig(config, secrets)

  config.data = orderFormCfg.data
  config.data.apps.splice(orderFormCfg.appId, 1)
  config.data.taxConfiguration = {}
  await setOrderFormConfig(config, secrets)
  logger.msgOk('Released successfully')
}

async function getOrderFormConfig(config, secrets = null) {
  logger.msgPad('getting orderForm configuration')
  if (!secrets) secrets = config.base
  const { account } = config.base.vtex
  const axiosConfig = {
    url: `https://${account}.vtexcommercestable.com.br/api/checkout/pvt/configuration/orderForm`,
    method: 'get',
    headers: {
      'X-VTEX-API-AppKey': secrets.vtex.apiKey,
      'X-VTEX-API-AppToken': secrets.vtex.apiToken,
    },
  }

  const result = await http.request(axiosConfig)
  const appId = result?.data?.apps?.findIndex((app) => app.id === 'e2e')
  const workspace = appId >= 0 ? result?.data?.apps[appId]?.fields[0] : null
  const startTime = appId >= 0 ? result?.data?.apps[appId]?.fields[1] : null

  return { startTime, workspace, appId, data: result?.data }
}

async function setOrderFormConfig(config, secrets) {
  logger.msgPad('setting orderForm configuration')
  if (!secrets) secrets = config.base
  const { account } = config.base.vtex
  const url = `https://${account}.vtexcommercestable.com.br/api/checkout/pvt/configuration/orderForm`
  const headers = {
    'X-VTEX-API-AppKey': secrets.vtex.apiKey,
    'X-VTEX-API-AppToken': secrets.vtex.apiToken,
  }

  const axiosConfig = { url, method: 'post', headers, data: config.data }
  const result = await http.request(axiosConfig)

  if (!/20./.test(result?.status)) {
    system.crash(
      'Failed to set up orderForm configuration',
      `HTTP status: ${result?.status}`
    )
  }
}

async function setAppConfig(config, secrets) {
  logger.msgOk('Configuring apps')
  if (!secrets) secrets = config.base
  const { account } = config.base.vtex
  const { prefix } = config.workspace
  const workspace = config.workspace.name
  const orderFormCfg = await getOrderFormConfig(config, secrets)
  const apps = config.workspace.reserveAccount.setup

  config.data = orderFormCfg.data
  for (const id in apps) {
    if (apps[id].toLowerCase() === 'orderform') {
      config.data.taxConfiguration = {
        url: `https://${workspace}--${account}.myvtex.com/${prefix}/checkout/order-tax`,
        authorizationHeader: secrets.vtex.authorizationHeader,
        allowExecutionAfterErrors: false,
        integratedAuthentication: false,
        appId: Date.now(),
      }
      // eslint-disable-next-line no-await-in-loop
      await setOrderFormConfig(config, secrets)
    } else if (apps[id].includes('@')) {
      logger.msgPad(`configuring ${apps[id]}`)
      const [app, version] = apps[id].split('@')
      const graphQLApp = 'vtex.apps-graphql@3.x'
      const url = `https://${account}.myvtex.com/_v/private/admin-graphql-ide/v0/${graphQLApp}`
      // eslint-disable-next-line no-await-in-loop
      const user = await toolbelt.getLocalToken()
      const headers = { Cookie: `${secrets.vtex.authCookieName}=${user.token}` }
      let check = null

      const query =
        'mutation' +
        '($app:String, $version:String, $settings:String)' +
        '{saveAppSettings(app:$app, version:$version, settings:$settings){message}}'

      const variables = {
        app,
        version,
        settings: `{"targetWorkspace": "${workspace}"}`,
      }

      const axiosConfig = {
        url,
        method: 'post',
        headers,
        data: { query, variables },
      }

      try {
        // eslint-disable-next-line no-await-in-loop
        const result = await http.request(axiosConfig)

        check = RegExp(workspace).test(
          result?.data?.data?.saveAppSettings?.message
        )
      } catch (_e) {
        check = false
      }

      if (!check) {
        logger.msgError(`Failed to configure ${apps[id]}`, true)
        logger.msgPad('Releasing account level resources')
        // eslint-disable-next-line no-await-in-loop
        await this.releaseAccount(config, secrets)
        system.crash('Failed to configure app', apps[id])
      }
    }
  }
}

// If called outside cy-runner, let's deal with it
if (action) checkAccount().then((r) => r)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/node/storage.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
const fs = require('fs')
const path = require('path')

const jsYaml = require('js-yaml')

const system = require('./system')
const logger = require('./logger')
const schema = require('./schema')

exports.read = (file) => {
  try {
    return fs.readFileSync(file, { encoding: 'utf-8' })
  } catch (e) {
    system.crash(`Failed to read the ${file}`, e)
  }
}

exports.size = (file) => {
  try {
    return fs.statSync(file).size
  } catch (e) {
    system.crash(`Failed to get size of ${file}`, e)
  }
}

exports.copy = (source, destination) => {
  try {
    return fs.copyFileSync(source, destination)
  } catch (e) {
    system.crash(`Failed to copy ${source} to ${destination}`, e)
  }
}

exports.link = (source, destination) => {
  try {
    return fs.symlinkSync(source, destination)
  } catch (e) {
    system.crash(`Failed to link ${source} to ${destination}`, e)
  }
}

exports.unLink = (source) => {
  try {
    return fs.unlinkSync(source)
  } catch (e) {
    system.crash(`Failed to unlink ${source}`, e)
  }
}

exports.exists = (fileOrDirectory) => {
  try {
    return fs.existsSync(fileOrDirectory)
  } catch (e) {
    system.crash(`Failed to check ${fileOrDirectory}`, e)
  }
}

exports.append = (msg, file) => {
  try {
    return fs.appendFileSync(file, msg)
  } catch (e) {
    system.crash(`Failed to append ${msg} to ${file}`, e)
  }
}

exports.write = (msg, file) => {
  try {
    return fs.writeFileSync(file, msg)
  } catch (e) {
    system.crash(`Failed to create ${file}`, e)
  }
}

exports.delete = (file) => {
  try {
    if (this.exists(file)) return fs.rmSync(file, { recursive: true })
  } catch (e) {
    system.crash(`Failed to delete ${file}`, e)
  }
}

exports.makeDir = (directory) => {
  try {
    if (!this.exists(directory)) return fs.mkdirSync(directory)
  } catch (e) {
    // TODO: Fix the error when got error creating logs folder
    // If the dir to be create = logs, the error will be in loop
    system.crash(`Failed to create ${directory}`, e)
  }
}

exports.readYaml = (jsonFile) => {
  try {
    return jsYaml.load(this.read(jsonFile, 'utf-8'))
  } catch (e) {
    system.crash(`Invalid JSON/YAML file: ${jsonFile}`, e)
  }
}

exports.loadConfig = (yamlFile) => {
  // Check if you are inside cy-runner
  logger.msgOk('Checking base path')
  if (this.exists('cy-runner')) {
    system.crash('Wrong start path', 'You must be inside cy-runner folder', {
      dump: false,
    })
  }

  // Fill full path for yaml config
  yamlFile = path.join(system.basePath(), yamlFile)
  const parentYamlFile = path.join(system.rootPath(), yamlFile)

  if (this.exists(parentYamlFile)) yamlFile = parentYamlFile
  if (!this.exists(yamlFile)) system.crash(`${yamlFile} not found`)

  try {
    const data = this.read(yamlFile)
    const config = jsYaml.load(data)

    schema.validateConfig(config)
      ? logger.msgPad(yamlFile.replace(system.rootPath(), '.'))
      : system.crash(`Unknown error loading ${yamlFile}`)

    return config
  } catch (e) {
    system.crash(`Invalid ${yamlFile.replace(system.rootPath(), '.')}`, e)
  }
}

exports.writeJson = (config, jsonFile) => {
  try {
    this.write(JSON.stringify(config), jsonFile)
    logger.msgPad(jsonFile.replace(system.basePath(), '.'))
  } catch (e) {
    system.crash(`Failed to create ${jsonFile}`, e)
  }
}

exports.createStateFiles = (config) => {
  try {
    const { stateFiles } = config.base
    const SIZE = stateFiles.length
    const PLURAL = SIZE > 1 ? 'files' : 'file'

    if (SIZE) {
      logger.msgOk(`Creating state ${PLURAL}`)
      stateFiles.forEach((stateFile) => {
        logger.msgPad(stateFile)
        this.write('{}', path.join(system.cyRunnerPath(), stateFile))
      })
    }
  } catch (e) {
    system.crash('Failed to create a state file', e)
  }
}

// ENGINEERS-465
exports.keepStateFiles = (config) => {
  try {
    const { stateFiles } = config.base

    logger.msgWarn('Moving state files')
    stateFiles.forEach((stateFile) => {
      const SRC = path.join(system.cyRunnerPath(), stateFile)
      const DST = path.join(logger.logPath(), stateFile)

      logger.msgPad(`${stateFile} -> ${DST.replace(system.basePath(), '.')}`)

      this.copy(SRC, DST)
    })
    logger.msgOk('State files moved successfully')
  } catch (e) {
    system.crash('Failed to keep state files', e)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/test/cypress/plugins/index.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
// / <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

/**
 * @type {Cypress.PluginConfig}
 */
// eslint-disable-next-line no-unused-vars
module.exports = (on, config) => {
  // `on` is used to hook into various events Cypress emits
  // `config` is the resolved Cypress config
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/test/cypress/integration/todo.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
// / <reference types="cypress" />

// Welcome to Cypress!
//
// This spec file contains a variety of sample tests
// for a tod o list app that are designed to demonstrate
// the power of writing tests in Cypress.
//
// To learn more about how Cypress works and
// what makes it such an awesome testing tool,
// please read our getting started guide:
// https://on.cypress.io/introduction-to-cypress

describe('example to-do app', () => {
  beforeEach(() => {
    // Cypress starts out with a blank slate for each test
    // so we must tell it to visit our website with the `cy.visit()` command.
    // Since we want to visit the same URL at the start of all our tests,
    // we include it in our beforeEach function so that it runs before each test
    cy.visit('https://example.cypress.io/todo')
  })

  it('displays two todo items by default', () => {
    // We use the `cy.get()` command to get all elements that match the selector.
    // Then, we use `should` to assert that there are two matched items,
    // which are the two default items.
    cy.get('.todo-list li').should('have.length', 2)

    // We can go even further and check that the default todos each contain
    // the correct text. We use the `first` and `last` functions
    // to get just the first and last matched elements individually,
    // and then perform an assertion with `should`.
    cy.get('.todo-list li').first().should('have.text', 'Pay electric bill')
    cy.get('.todo-list li').last().should('have.text', 'Walk the dog')
  })

  it('can add new todo items', () => {
    // We'll store our item text in a variable so we can reuse it
    const newItem = 'Feed the cat'

    // Let's get the input element and use the `type` command to
    // input our new list item. After typing the content of our item,
    // we need to type the enter key as well in order to submit the input.
    // This input has a data-test attribute so we'll use that to select the
    // element in accordance with best practices:
    // https://on.cypress.io/selecting-elements
    cy.get('[data-test=new-todo]').type(`${newItem}{enter}`)

    // Now that we've typed our new item, let's check that it actually was added to the list.
    // Since it's the newest item, it should exist as the last element in the list.
    // In addition, with the two default items, we should have a total of 3 elements in the list.
    // Since assertions yield the element that was asserted on,
    // we can chain both of these assertions together into a single statement.
    cy.get('.todo-list li')
      .should('have.length', 3)
      .last()
      .should('have.text', newItem)
  })

  it('can check off an item as completed', () => {
    // In addition to using the `get` command to get an element by selector,
    // we can also use the `contains` command to get an element by its contents.
    // However, this will yield the <label>, which is lowest-level element that contains the text.
    // In order to check the item, we'll find the <input> element for this <label>
    // by traversing up the dom to the parent element. From there, we can `find`
    // the child checkbox <input> element and use the `check` command to check it.
    cy.contains('Pay electric bill')
      .parent()
      .find('input[type=checkbox]')
      .check()

    // Now that we've checked the button, we can go ahead and make sure
    // that the list element is now marked as completed.
    // Again we'll use `contains` to find the <label> element and then use the `parents` command
    // to traverse multiple levels up the dom until we find the corresponding <li> element.
    // Once we get that element, we can assert that it has the completed class.
    cy.contains('Pay electric bill')
      .parents('li')
      .should('have.class', 'completed')
  })

  context('with a checked task', () => {
    beforeEach(() => {
      // We'll take the command we used above to check off an element
      // Since we want to perform multiple tests that start with checking
      // one element, we put it in the beforeEach hook
      // so that it runs at the start of every test.
      cy.contains('Pay electric bill')
        .parent()
        .find('input[type=checkbox]')
        .check()
    })

    it('can filter for uncompleted tasks', () => {
      // We'll click on the "active" button in order to
      // display only incomplete items
      cy.contains('Active').click()

      // After filtering, we can assert that there is only the one
      // incomplete item in the list.
      cy.get('.todo-list li')
        .should('have.length', 1)
        .first()
        .should('have.text', 'Walk the dog')

      // For good measure, let's also assert that the task we checked off
      // does not exist on the page.
      cy.contains('Pay electric bill').should('not.exist')
    })

    it('can filter for completed tasks', () => {
      // We can perform similar steps as the test above to ensure
      // that only completed tasks are shown
      cy.contains('Completed').click()

      cy.get('.todo-list li')
        .should('have.length', 1)
        .first()
        .should('have.text', 'Pay electric bill')

      cy.contains('Walk the dog').should('not.exist')
    })

    it('can delete all completed tasks', () => {
      // First, let's click the "Clear completed" button
      // `contains` is actually serving two purposes here.
      // First, it's ensuring that the button exists within the dom.
      // This button only appears when at least one task is checked
      // so this command is implicitly verifying that it does exist.
      // Second, it selects the button so we can click it.
      cy.contains('Clear completed').click()

      // Then we can make sure that there is only one element
      // in the list and our element does not exist
      cy.get('.todo-list li')
        .should('have.length', 1)
        .should('not.have.text', 'Pay electric bill')

      // Finally, make sure that the clear button no longer exists.
      cy.contains('Clear completed').should('not.exist')
    })
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/test/cypress/support/index.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'

// Alternatively you can use CommonJS syntax:
// require('./commands')

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/test/cypress/support/commands.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/test/cypress/fixtures/example.json from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "Using fixtures to represent data",
  "email": "hello@cypress.io",
  "body": "Fixtures are a great way to mock data for responses to routes"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/plugins/index.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
const readXlsx = require('./read-xlsx.js')

module.exports = (on) => {
  on('task', {
    readXlsx: readXlsx.read,
  })
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/plugins/read-xlsx.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
const fs = require('fs')

const XLSX = require('xlsx')

const read = ({ file, sheet }) => {
  const buf = fs.readFileSync(file)
  const workbook = XLSX.read(buf, { type: 'buffer' })

  return XLSX.utils.sheet_to_json(workbook.Sheets[sheet])
}

module.exports = {
  read,
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/support/graphql_operations.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
export const GRAPHL_OPERATIONS = {
  CreateOrganizationRequest: 'CreateOrganizationRequest',
  GetUsers: 'GetUsers',
  GetCostCentersByOrganizationIdStorefront:
    'GetCostCentersByOrganizationIdStorefront',
  GetCostCenterStorefront: 'GetCostCenterStorefront',
  addToCart: 'addToCart',
  CreateQuote: 'CreateQuote',
  UpdateQuote: 'UpdateQuote',
  GetQuotes: 'GetQuotes',
  ImpersonateUser: 'ImpersonateUser',
  Session: 'Session',
  GetOrderForm: 'GetOrderForm',
  CheckImpersonation: 'ViewLists',
  Autocomplete: 'Autocomplete',
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/support/validation_text.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
export const TOAST_MSG = {
  added: /added/i,
  updated: /updated/i,
  deleted: /deleted/i,
  addedToTheCart: /added to the cart/i,
  initializing: /initializing/i,
  impersonatePermissionError: /do not have permission to impersonate/i,
  userAlreadyRegisteredInThisOrganization: /this organization/,
}

export const BUTTON_LABEL = {
  create: /create/i,
  remove: /Remove/i,
  cancel: /cancel/i,
  save: /save/i,
  delete: /delete/i,
  back: /back/i,
  completeOrder: /Complete Order/i,
  AddToCart: /Add to Cart/i,
  QuickOrder: /Quick Order/i,
  QuoteDetails: 'Quote Details',
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/support/index.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
import './common/commands'
import './b2b/env_organization'
import './b2b/env_quotes'
import './commands'
import './common/api_commands'
import './common/env_orders'

// Configure it to preserve cookies
Cypress.Cookies.defaults({
  preserve: /VtexIdclientAutCookie$|JSESSIONID/,
})

Cypress.on('uncaught:exception', (_, __) => {
  return false
})

// Reference:https://stackoverflow.com/questions/48661153/cypress-seems-to-have-stalled
// We are using below code in affirm payment
Cypress.on('window:before:load', (win) => {
  if (win.location.href.includes('sandbox')) {
    Object.defineProperty(win, 'self', {
      get: () => {
        return window.top
      },
    })
  }
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/support/extract.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
const GmailAPI = require('./common/gmail')

const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms))

function extractAccessCode(message) {
  if (message) {
    const regex = /<strong>(\d.*)<\/strong>/

    return message.includes('access code') ? message.match(regex)[1] : '0'
  }

  return '0'
}

export async function getAccessToken(email, gmailCreds, accessToken = null) {
  const gmail = new GmailAPI(gmailCreds)
  const ToEmail = email.replace('+', '%2B')
  let currentAccessToken
  const totalRetry = 8

  await gmail.getAcceToken(gmailCreds)

  /* eslint-disable no-await-in-loop */
  for (let currentRetry = 0; currentRetry <= totalRetry; currentRetry++) {
    currentAccessToken = extractAccessCode(
      await gmail.readInboxContent(
        new URLSearchParams(
          `from:noreply@vtexcommerce.com.br+to:${ToEmail}`
        ).toString(),
        gmailCreds
      )
    )
    if (accessToken === null || currentAccessToken !== accessToken) {
      return currentAccessToken
    }

    await delay(5500)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/support/commands.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
import selectors from './common/selectors.js'
import {
  searchInMasterData,
  deleteDocumentInMasterData,
} from './common/wipe.js'
import { performImpersonation } from './b2b/common.js'
import 'cypress-file-upload'
import { fillContactInfo, scroll } from './common/support.js'

function closeModalIfOpened() {
  cy.get('body').then(($body) => {
    if ($body.find('div[class*=vtex-modal__close]').length) {
      cy.qe(`Some modal been opened in the page. Let's close it`)
      cy.get('div[class*=vtex-modal__close]').click()
    }
  })
}

Cypress.Commands.add('closeMenuIfOpened', () => {
  cy.addDelayBetweenRetries(5000)
  cy.get('button[class*=closeIconButton]').then(($el) => {
    if (Cypress.dom.isVisible($el)) {
      cy.get('button[class*=closeIconButton]').first().click()
    }
  })
})

Cypress.Commands.add('searchInMasterData', searchInMasterData)
Cypress.Commands.add('deleteDocumentInMasterData', deleteDocumentInMasterData)
Cypress.Commands.add('performImpersonation', performImpersonation)

Cypress.Commands.add('waitForSession', (selector = null) => {
  cy.qe('Wait for the Session to be called in the page')
  cy.getVtexItems().then((vtex) => {
    cy.intercept('POST', `${vtex.baseUrl}/**`, (req) => {
      if (req.body.operationName === 'Session') {
        req.continue()
      }
    }).as('Session')

    if (selector) {
      cy.qe(`Click this ${selector}`)
      cy.get(selector).last().click()
    }

    cy.wait('@Session', { timeout: 20000 })
  })
})

Cypress.Commands.add(
  'waitForGraphql',
  (operationName, selector = null, contains = null, timeout = 30000) => {
    cy.getVtexItems().then((vtex) => {
      cy.intercept('POST', `${vtex.baseUrl}/**`, (req) => {
        if (req.body.operationName === operationName) {
          req.continue()
        }
      }).as(operationName)

      if (selector && contains) {
        cy.scrollTo('top')
        cy.qe(`Click the button which has content ${selector} in it`)
        cy.contains(selector).should('be.visible').click()
      } else if (selector) {
        cy.qe(`Click the button which has selector ${selector} in it`)
        cy.get(selector).should('be.visible').last().click()
      } else if (contains) {
        cy.qe(`Click the button which has content ${contains} in it`)
        cy.contains(contains).should('be.visible').click()
      }

      cy.qe(
        `Wait for this graphql operation  ${operationName} to be called in the page`
      )
      cy.wait(`@${operationName}`, { timeout })
    })
  }
)

Cypress.Commands.add('fillAddressInCostCenter', (costCenter) => {
  const { country, postalCode, street, receiverName } = costCenter

  cy.qe(`For country dropdown, select ${country}`)
  cy.get(selectors.Country).should('not.be.disabled').select(country)
  cy.intercept('GET', `**/${postalCode}`).as('POSTALCODE')
  cy.qe(`For postalCode field, type ${postalCode}`)
  cy.get(selectors.PostalCode)
    .clear()
    .type(postalCode, { delay: 30 })
    .should('have.value', postalCode)
  cy.wait('@POSTALCODE')
  cy.qe(`For street field, type ${street}`)
  cy.get(selectors.Street)
    .clear()
    .type(street, { delay: 20 })
    .should('have.value', street)
  cy.qe(`Check state field is autofilled and not empty`)
  cy.get(selectors.State).invoke('val').should('not.be.empty')
  cy.qe(`Check city field is autofilled and not empty`)
  cy.get(selectors.City).invoke('val').should('not.be.empty')
  cy.qe(`For receiverName field, clear and type ${receiverName}`)
  cy.get(selectors.ReceiverNameinB2B)
    .clear()
    .type(receiverName)
    .should('have.value', receiverName)
})

Cypress.Commands.add(
  'gotoMyOrganization',
  (waitforSession = true, salesRepOrManager = false) => {
    cy.qe('ProfileLabel should be visible')
    cy.get(selectors.ProfileLabel).should('be.visible')

    cy.url().then((url) => {
      if (!url.includes('account')) {
        cy.qe('We are not in account page')
        cy.qe('Click SignInBtn')
        cy.get(selectors.SignInBtn).click()
        cy.qe('Click MyAccount')
        cy.get(selectors.MyAccount).click()
        if (waitforSession) cy.waitForSession()
      }

      closeModalIfOpened()
      cy.qe('Click MyOrganization link')
      cy.get(selectors.MyOrganization, { timeout: 40000 })
        .should('be.visible')
        .click()
      const noOfdivision = salesRepOrManager ? 2 : 4

      cy.qe(
        `This selector ${selectors.MyOrganizationCostCenterUserDiv} should have length ${noOfdivision} in current page`
      )

      cy.get(selectors.MyOrganizationCostCenterUserDiv).should(
        'have.length',
        noOfdivision
      )
    })
  }
)
Cypress.Commands.add('gotoCostCenter', (costCenter) => {
  cy.get('body').then(($body) => {
    if ($body.find('div[class*=pageHeader__title]').length) {
      cy.get('div[class*=pageHeader__title]')
        .invoke('text')
        .then((text) => {
          if (!text.includes('Cost Center')) {
            cy.qe('Cost Center text is not found in the page')
            cy.qe("So, let's open the costCenter")
            cy.contains(costCenter).click()
          } else {
            cy.qe('Already in costcenter page')
          }
        })
    }
  })
})

Cypress.Commands.add('gotoMyQuotes', () => {
  cy.get(selectors.ProfileLabel, { timeout: 20000 }).should('be.visible')
  cy.scrollTo('top')
  cy.get('body').then(($body) => {
    if (!$body.find(selectors.ToggleFields).length) {
      cy.get(selectors.MyQuotes, { timeout: 10000 })
        .should('be.visible')
        .click()
    }
  })
  cy.get(selectors.QuotesToolBar, { timeout: 20000 }).should('be.visible')
})

Cypress.Commands.add('gotoQuickOrder', (b2b = false) => {
  cy.location().then((loc) => {
    let closeMenu = false

    if (loc.pathname.includes('quickorder')) closeMenu = true
    if (b2b) {
      closeMenu && cy.closeMenuIfOpened()
      cy.get(selectors.Menu).should('be.visible').click()
      cy.get(selectors.QuickOrder).should('be.visible').click()
    } else {
      cy.qe(
        'Visit the QuickOrder home page: if the profile label is visible, then the profile label should contain Hello'
      )
      cy.visit('/quickorder')
      cy.get(selectors.ProfileLabel, { timeout: 20000 })
        .should('be.visible')
        .should('have.contain', `Hello,`)
    }

    cy.qe(`The Url should contain quickorder`)
    cy.url().should('include', 'quickorder')
  })
})

Cypress.Commands.add('searchProductinB2B', (product, available = true) => {
  cy.url().then((url) => {
    if (url.includes('checkout')) {
      cy.visit('/')
    }

    cy.get(selectors.ProfileLabel).should('be.visible')
    // Search product in search bar
    cy.get(selectors.Search)
      .first()
      .should('be.visible')
      .should('be.enabled')
      .clear()
      .type(product, { force: true })
      .type('{enter}', { force: true })
    if (available) {
      cy.get(selectors.searchResult).should('be.visible')
      cy.get('article div[class*=storefront-permissions-ui]')
        .should('be.visible')
        .first()
        .scrollIntoView()
    }
  })
})

Cypress.Commands.add('checkStatusAndReject', (expectedStatus) => {
  cy.get(selectors.QuoteStatus)
    .first()
    .invoke('text')
    .then((currentStatus) => {
      if (currentStatus === expectedStatus) return cy.wrap(false)

      return cy.wrap(true)
    })
})

Cypress.Commands.add(
  'checkAndFillData',
  (selector, expectedText, position = 0) => {
    cy.get(selector)
      .eq(position)
      .invoke('val')
      .then((text) => {
        if (text !== expectedText) {
          cy.get(selector).eq(position).clear().type(expectedText)

          return cy.wrap(true)
        }

        return cy.wrap(false)
      })
  }
)

Cypress.Commands.add('orderProduct', () => {
  cy.qe('Fill contact information in checkout page')
  cy.get(selectors.FirstName).then(($el) => {
    if (Cypress.dom.isVisible($el)) {
      fillContactInfo()
    }
  })
  cy.qe('To make payment select Promissory payment')
  cy.get(selectors.PromissoryPayment).should('be.visible').click()
  cy.get(selectors.BuyNowBtn).last().should('be.visible').click()
  cy.get(selectors.Search, { timeout: 30000 }).should('be.visible')
})

Cypress.Commands.add('openStoreFront', (login = false) => {
  cy.intercept('**/event-api/v1/*/event').as('events')
  cy.qe('Visit store front')
  cy.visit('/')
  cy.wait('@events')
  if (login === true) {
    cy.get(selectors.ProfileLabel, { timeout: 20000 })
      .should('be.visible')
      .should('have.contain', `Hello,`)
  }

  scroll()
})

Cypress.Commands.add(
  'addNewLocation',
  (country, postalCode, street, city, retypePostalCode = false) => {
    cy.openStoreFront()
    cy.qe(
      'Address container should be visible in the top left of the home page'
    )
    cy.get(selectors.addressContainer, { timeout: 30000 })
      .should('be.visible')
      .click()
    cy.qe('Select a country')
    cy.get(selectors.countryDropdown).select(country)
    cy.qe('Type a postalcode')
    cy.get(selectors.addressInputContainer)
      .first()
      .clear()
      .should('be.visible')
      .type(postalCode, { delay: 10 })
    cy.get(selectors.SaveButtonInChangeLocationPopUp).should('be.visible')
    cy.qe('Type street address in address input')
    cy.get(selectors.Address)
      .contains('Address Line 1')
      .parent()
      .within(() => {
        cy.get(selectors.InputText).should('be.visible').clear().type(street)
      })
    cy.qe('Type a city')
    cy.get(selectors.Address)
      .contains('City')
      .parent()
      .within(() => {
        cy.get(selectors.InputText).should('be.visible').clear().type(city)
      })

    if (retypePostalCode) {
      cy.get(selectors.addressInputContainer)
        .first()
        .clear()
        .should('be.visible')
        .type(postalCode, { delay: 10 })
    }

    cy.waitForGraphql('setRegionId', selectors.SaveButtonInChangeLocationPopUp)
    cy.once('uncaught:exception', () => false)
  }
)

Cypress.Commands.add(
  'openProduct',
  (product, detailPage = false, searchPage = false) => {
    // Search product in search bar
    cy.get(selectors.Search).should('be.not.disabled').should('be.visible')
    cy.qe('Search product in search bar')
    cy.get(selectors.Search)
      .should('be.visible')
      .should('be.enabled')
      .clear()
      .type(product)
      .type('{enter}')
    // Page should load successfully now Filter should be visible
    cy.qe('Search result page should load successfully')
    cy.get(selectors.searchResult).should('have.text', product.toLowerCase())
    cy.get(selectors.FilterHeading, { timeout: 30000 }).should('be.visible')
    if (searchPage) {
      cy.qe(
        "If the search page is true, then it should show the message 'Shipping: Unavailable for'"
      )
      cy.get(selectors.locationUnavailable)
        .should('be.visible')
        .contains('Shipping: Unavailable for')
    }

    if (detailPage) {
      cy.qe('If detailPage is true,then it should go to product detail page')
      cy.gotoProductDetailPage()
    } else {
      cy.log('Visiting detail page is disabled')
    }
  }
)

function visitOrganizationPage() {
  cy.url().then((url) => {
    if (!url.includes('account')) {
      cy.get(selectors.ProfileLabel).should('be.visible')
      cy.get(selectors.SignInBtn).click()
      cy.get(selectors.MyAccount).click()
      cy.waitForSession()
    }

    closeModalIfOpened()
    cy.get('a[href*="profile"]').should('be.visible')
    cy.get('a[href*="wishlist"]').should('be.visible')
    cy.contains(selectors.QuotesAndSavedCarts).should('be.visible')
  })
}

Cypress.Commands.add('organizationShouldNotShowInProfile', () => {
  visitOrganizationPage()
  cy.get(selectors.MyOrganization, { timeout: 20000 }).should('not.exist')
})

Cypress.Commands.add('organizationShouldShowInProfile', () => {
  visitOrganizationPage()
  cy.get(selectors.MyOrganization, { timeout: 25000 }).should('be.visible')
})

const fedexJson = 'fedexPayload.json'

Cypress.Commands.add('setAppSettingstoJSON', (key, value) => {
  cy.readFile(fedexJson).then((items) => {
    items[key] = value
    cy.writeFile(fedexJson, items)
  })
})

Cypress.Commands.add('getAppSettingstoJSON', () => {
  cy.readFile(fedexJson).then((items) => {
    return items
  })
})

Cypress.Commands.add('hideSla', (hide) => {
  cy.readFile(fedexJson).then((items) => {
    const { slaSettings } = items.config.data.getAppSettings

    for (const ship in slaSettings) {
      slaSettings[ship].hidden = hide
    }

    return slaSettings
  })
})

Cypress.Commands.add('readSlaSettings', () => {
  cy.readFile(fedexJson).then((items) => {
    const { slaSettings } = items.config.data.getAppSettings

    return slaSettings
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/fixtures/pack.json from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "packed": {
    "ItemsToPack": [
      {
        "ID": 1,
        "Dim1": 1,
        "Dim2": 1,
        "Dim3": 1,
        "Quantity": 1
      },
      {
        "ID": 2,
        "Dim1": 1,
        "Dim2": 2,
        "Dim3": 2,
        "Quantity": 1
      }
    ]
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/adyen/2.4-discountProduct.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/expect-expect */
import {
  loginViaCookies,
  preserveCookie,
} from '../../support/common/support.js'
import { discountProduct } from '../../support/adyen/outputvalidation'
import {
  getTestVariables,
  checkoutProduct,
} from '../../support/common/testcase.js'
import { completePaymentWithDinersCard } from '../../support/adyen/testcase.js'
import selectors from '../../support/common/selectors.js'

const { prefix, total } = discountProduct

describe(`${prefix} Scenarios`, () => {
  loginViaCookies()

  const { orderIdEnv } = getTestVariables(prefix)

  checkoutProduct(discountProduct)

  it(`In ${prefix} - Verifying total amounts and discount for a discounted product`, () => {
    // Verify Total
    cy.verifyTotal(total)
    // Verify Discounts
    cy.qe('Discounts should be visible')
    cy.get(selectors.Discounts).last().should('be.visible')
  })

  completePaymentWithDinersCard(prefix, orderIdEnv)

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/adyen/wipe.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
import {
  deleteAdyenWebhook,
  deleteAccountHoldersFromMasterData,
} from '../../support/adyen/adyen_apis.js'
import { loginViaCookies } from '../../support/common/support.js'
import { setWorkspaceAndGatewayAffiliations } from '../../support/common/testcase.js'

describe('Wipe Adyen in dynamic environment', () => {
  loginViaCookies()

  setWorkspaceAndGatewayAffiliations({ wipe: true })
  deleteAdyenWebhook()
  deleteAccountHoldersFromMasterData()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/adyen/2.7-promotionalProduct.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/expect-expect */
import {
  loginViaCookies,
  preserveCookie,
  updateRetry,
} from '../../support/common/support.js'
import { promotionProduct } from '../../support/adyen/outputvalidation'
import {
  getTestVariables,
  checkoutProduct,
} from '../../support/common/testcase'
import { completePaymentWithDinersCard } from '../../support/adyen/testcase.js'

describe('Promotional Product scenarios', () => {
  loginViaCookies()

  const { prefix } = promotionProduct

  const { orderIdEnv } = getTestVariables(prefix)

  checkoutProduct(promotionProduct)

  it(`In ${prefix} - Verify free product is added`, updateRetry(3), () => {
    cy.qe('Verify free product is added')
    cy.get('span[class="new-product-price"]')
      .first()
      .should('have.text', 'Free')
  })

  completePaymentWithDinersCard(prefix, orderIdEnv)

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/adyen/2.2-singleProduct.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/expect-expect */
import { completePaymentWithDinersCard } from '../../support/adyen/testcase'
import { singleProduct } from '../../support/adyen/outputvalidation'
import {
  loginViaCookies,
  preserveCookie,
  updateRetry,
} from '../../support/common/support'
import { getTestVariables } from '../../support/common/testcase'

const { prefix, postalCode, productName, productQuantity } = singleProduct

const singleProductEnvs = getTestVariables(prefix)
const { orderIdEnv } = singleProductEnvs

describe(`${prefix} scenarios`, () => {
  loginViaCookies()

  it(`In ${prefix} - Adding Product to Cart`, updateRetry(3), () => {
    // Search the product
    cy.searchProduct(productName)
    // Add product to cart
    cy.addProduct(productName)
  })

  it(
    `In ${prefix} - Updating product quantity to ${productQuantity}`,
    updateRetry(4),
    () => {
      cy.updateProductQuantity(productName, {
        quantity: productQuantity,
        verifySubTotal: false,
      })
    }
  )

  it(`In ${prefix} - Updating Shipping Information`, updateRetry(4), () => {
    // Update Shipping Section
    cy.updateShippingInformation({
      postalCode,
    })
  })

  completePaymentWithDinersCard(prefix, orderIdEnv)

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/adyen/post-setup.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { createAdyenWebhook } from '../../support/adyen/adyen_apis.js'
import {
  updateAdyenConnectorSettings,
  updateAdyenPlatformSettings,
} from '../../support/adyen/graphql.js'
import {
  verifyAdyenConnectorSettings,
  verifyAdyenPlatformSettings,
  createOnBoardingLink,
} from '../../support/adyen/testcase.js'
import {
  loginViaCookies,
  preserveCookie,
} from '../../support/common/support.js'
import { setWorkspaceAndGatewayAffiliations } from '../../support/common/testcase.js'

describe('Setting up adyen payments in dynamic environment', () => {
  loginViaCookies()

  updateAdyenConnectorSettings()
  verifyAdyenConnectorSettings()
  updateAdyenPlatformSettings()
  verifyAdyenPlatformSettings()
  createAdyenWebhook()
  setWorkspaceAndGatewayAffiliations({ afterAuthorization: true })
  createOnBoardingLink(true)

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/adyen/2.10-partialRefund.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/expect-expect */
import { multiProduct } from '../../support/adyen/outputvalidation.js'
import { refund } from '../../support/common/refund_apis.js'
import { getTestVariables } from '../../support/common/testcase.js'
import {
  loginViaCookies,
  preserveCookie,
} from '../../support/common/support.js'
import { getRefundPayload } from '../../support/common/refund.js'
import { verifyOrderInAdyen } from '../../support/adyen/adyen_apis.js'
import { loginToAdyen } from '../../support/adyen/testcase.js'

describe('Testing Adyen transaction API for partial refund', () => {
  const multiProductEnvs = getTestVariables(multiProduct.prefix)
  const { orderIdEnv } = multiProductEnvs

  loginViaCookies()

  loginToAdyen()

  it('Verify whether we have an order to request for partial refund', () => {
    cy.getOrderItems().then((order) => {
      if (!order[orderIdEnv]) {
        throw new Error('Order id is missing')
      }
    })
  })

  // Request partial refund for the ordered product added in 2.3-multiProduct.spec.js
  refund(
    {
      total: multiProduct.getPartialRefundTotal, // Amount
      title: 'partial', // Refund Type for test case title
      env: orderIdEnv, // variable name where we stored the orderid in node environment
    },
    getRefundPayload,
    { startHandling: false }
  )

  verifyOrderInAdyen(multiProduct, multiProductEnvs, true)

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/adyen/2.1-graphql_testcases.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable padding-line-between-statements */
/* eslint-disable jest/expect-expect */
import {
  createAccountHolder,
  validateCreateAccountHolderResponse,
  refreshOnboarding,
  validateRefreshOnboardingResponse,
  closeAccountHolder,
  validateCloseAccountHolderResponse,
  sellers,
  validateSellersResponse,
  validateonboardingComplete,
  onboardingComplete,
  validateGetAdyenAccountResponse,
  getAdyenAccount,
  adyenAccountHolder,
  updateAccount,
  validateAdyenAccountHolderResponse,
  validateUpdateAccount,
} from '../../support/adyen/graphql_testcase'
import { graphql } from '../../support/common/graphql_utils'
import { updateRetry, loginViaCookies } from '../../support/common/support'
import { createAccount, schedule } from '../../support/adyen/outputvalidation'
import { getAllAccount, getOnBoarding } from '../../support/adyen/api_testcase'
import { createOnBoardingLink } from '../../support/adyen/testcase'
import { deleteAccountHoldersFromMasterData } from '../../support/adyen/adyen_apis.js'

const accountJson = '.account.json'
const accountHolderJson = '.accountholder.json'
const accountTokenJson = '.accounttoken.json'
const accountHolderCodeJson = '.accountholderCode.json'

const APP = 'vtex.adyen-platforms'
const { sellerId } = createAccount
const prefix = 'Graphql testcase'

//  Don't change the order,it has dependency.
describe('Adyen GraphQL Validation', () => {
  loginViaCookies()

  deleteAccountHoldersFromMasterData()

  it(`${prefix} - Create Account Holder`, updateRetry(2), () => {
    graphql(APP, createAccountHolder(createAccount), (response) => {
      validateCreateAccountHolderResponse(response)
      cy.qe('Write accountHolder information in accountJSON')
      cy.writeFile(accountJson, {
        newAccount: response.body.data.createAccountHolder.adyenAccountHolder,
      })
    })
  })

  it(`${prefix} - Get Sellers`, updateRetry(2), () => {
    graphql(APP, sellers(), validateSellersResponse)
  })

  it(`${prefix} - Get Adyen Account`, updateRetry(2), () => {
    graphql(APP, getAdyenAccount(), validateGetAdyenAccountResponse)
  })

  it(`${prefix} - Adyen Account Holder`, updateRetry(2), () => {
    graphql(
      APP,
      adyenAccountHolder(sellerId),
      validateAdyenAccountHolderResponse
    )
  })

  it(`${prefix} - Refresh On Boarding`, updateRetry(2), () => {
    cy.readFile(accountJson).then((items) => {
      graphql(
        APP,
        refreshOnboarding(items.newAccount.accountHolderCode),
        (response) => {
          validateRefreshOnboardingResponse(response)
          cy.qe(
            'Get accountToken from response.body.data.refreshOnboarding and write to accountTokenJson'
          )
          cy.writeFile(accountTokenJson, {
            accountToken: response.body.data.refreshOnboarding,
          })
        }
      )
    })
  })

  getAllAccount(sellerId)

  it(`${prefix} - updateAccount`, updateRetry(2), () => {
    cy.readFile(accountHolderJson).then((items) => {
      const accountCode = items.accountList
      for (const account in accountCode) {
        if (
          accountCode[account].accountHolderCode === items.accountHolderCode
        ) {
          cy.qe('Make items.accountHolderCode as Active')
          accountCode[account].status = 'Active'
        }
      }
      graphql(
        APP,
        updateAccount(accountCode[0].accountCode, schedule),
        validateUpdateAccount
      )
    })
  })

  it(`${prefix} - onboardingComplete`, updateRetry(2), () => {
    cy.readFile(accountHolderCodeJson).then((items) => {
      const { accountHolderCode } = items
      graphql(
        APP,
        onboardingComplete(accountHolderCode),
        validateonboardingComplete
      )
    })
  })

  createOnBoardingLink(false)

  getOnBoarding()

  it(`${prefix} - Close Account Holder`, updateRetry(2), () => {
    cy.readFile(accountJson).then((items) => {
      graphql(
        APP,
        closeAccountHolder(items.newAccount.accountHolderCode),
        validateCloseAccountHolderResponse
      )
    })
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/adyen/2.6-discountShipping.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/expect-expect */
import {
  loginViaCookies,
  preserveCookie,
} from '../../support/common/support.js'
import { discountShipping } from '../../support/adyen/outputvalidation'
import { completePaymentWithDinersCard } from '../../support/adyen/testcase.js'
import {
  getTestVariables,
  checkoutProduct,
} from '../../support/common/testcase.js'

const { prefix } = discountShipping

describe(`${prefix} Scenarios`, () => {
  loginViaCookies()

  const { orderIdEnv } = getTestVariables(prefix)

  checkoutProduct(discountShipping)

  completePaymentWithDinersCard(prefix, orderIdEnv)

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/adyen/2.5-externalSeller.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/expect-expect */
import {
  loginViaCookies,
  preserveCookie,
  updateRetry,
} from '../../support/common/support.js'
import { externalSeller } from '../../support/adyen/outputvalidation'
import { getTestVariables } from '../../support/common/testcase.js'
import { completePaymentWithDinersCard } from '../../support/adyen/testcase.js'

describe('External Seller Testcase', () => {
  loginViaCookies()

  const { prefix, product1Name, product2Name, postalCode, productQuantity } =
    externalSeller

  const { orderIdEnv } = getTestVariables(prefix)

  it(`In ${prefix} - Adding Product to Cart`, updateRetry(3), () => {
    // Search the product
    cy.searchProduct(product1Name)
    // Add product to cart
    cy.addProduct(product1Name, { proceedtoCheckout: false })
    // Search the product
    cy.searchProduct(product2Name)
    // Add product to cart
    cy.addProduct(product2Name, { proceedtoCheckout: true })
  })

  it(
    `In ${prefix} - Updating product quantity to ${productQuantity}`,
    updateRetry(4),
    () => {
      cy.updateProductQuantity(product1Name, {
        quantity: productQuantity,
        verifySubTotal: false,
      })
    }
  )

  it(`In ${prefix} - Updating Shipping Information`, updateRetry(4), () => {
    // Update Shipping Section
    cy.updateShippingInformation({ postalCode })
  })

  completePaymentWithDinersCard(prefix, orderIdEnv, externalSeller)

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/adyen/2.8-transactions.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/expect-expect */
import { loginViaCookies } from '../../support/common/support.js'
import {
  singleProduct,
  multiProduct,
  discountShipping,
  discountProduct,
  // externalSeller,
  promotionProduct,
} from '../../support/adyen/outputvalidation'
import { getTestVariables } from '../../support/common/testcase.js'
import {
  loginToAdyen,
  verifyProductInvoiceTestcase,
} from '../../support/adyen/testcase.js'

describe(`Transaction Scenarios`, () => {
  loginViaCookies()

  loginToAdyen()

  const singleProductEnvs = getTestVariables(singleProduct.prefix)
  const multiProductEnvs = getTestVariables(multiProduct.prefix)
  const discountShippingEnvs = getTestVariables(discountShipping.prefix)
  const discountProductEnvs = getTestVariables(discountProduct.prefix)
  // const externalSellerEnvs = getTestVariables(externalSeller.prefix)
  const promotionalProductEnvs = getTestVariables(promotionProduct.prefix)

  // single product
  verifyProductInvoiceTestcase(singleProduct, singleProductEnvs)

  // multi product
  verifyProductInvoiceTestcase(multiProduct, multiProductEnvs)

  // discount product
  verifyProductInvoiceTestcase(discountProduct, discountProductEnvs)

  // discount shipping product
  verifyProductInvoiceTestcase(discountShipping, discountShippingEnvs)

  // promotional product
  verifyProductInvoiceTestcase(promotionProduct, promotionalProductEnvs)

  // external sellet product
  // TODO - Enable this after verifying it is working fine
  // verifyProductInvoiceTestcase(externalSeller, externalSellerEnvs, true)
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/adyen/2.3-multiProduct.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/expect-expect */
import {
  loginViaCookies,
  updateRetry,
  preserveCookie,
} from '../../support/common/support.js'
import { multiProduct } from '../../support/adyen/outputvalidation'
import { completePaymentWithDinersCard } from '../../support/adyen/testcase'
import { getTestVariables } from '../../support/common/testcase'

const { prefix, product1Name, product2Name, postalCode, productQuantity } =
  multiProduct

const { orderIdEnv } = getTestVariables(prefix)

describe('Multi Product Testcase', () => {
  loginViaCookies()

  it(`In ${prefix} - Adding Product to Cart`, updateRetry(3), () => {
    // Search the product
    cy.searchProduct(product1Name)
    // Add product to cart
    cy.addProduct(product1Name, { proceedtoCheckout: false })
    // Search the product
    cy.searchProduct(product2Name)
    // Add product to cart
    cy.addProduct(product2Name, {
      proceedtoCheckout: true,
    })
  })

  it(
    `In ${prefix} - Updating product quantity to ${productQuantity}`,
    updateRetry(3),
    () => {
      // Update Product quantity to 2
      cy.updateProductQuantity(product1Name, {
        quantity: productQuantity,
        verifySubTotal: false,
      })
    }
  )

  it(`In ${prefix} - Updating Shipping Information`, updateRetry(4), () => {
    // Update Shipping Section
    cy.updateShippingInformation({ postalCode })
  })

  completePaymentWithDinersCard(prefix, orderIdEnv)

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/adyen/2.11-rest-apis.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
import {
  loginViaCookies,
  preserveCookie,
} from '../../support/common/support.js'
import { getAllAccount, Adyenhook } from '../../support/adyen/api_testcase'
import { hook, sellerAccount } from '../../support/adyen/outputvalidation'

describe('Rest-api-testcases', () => {
  loginViaCookies()

  getAllAccount(sellerAccount)

  Adyenhook(hook)

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/adyen/2.9-fullRefund-transaction.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/expect-expect */
import { singleProduct } from '../../support/adyen/outputvalidation.js'
import { refund } from '../../support/common/refund_apis.js'
import { getRefundPayload } from '../../support/common/refund.js'
import { getTestVariables } from '../../support/common/testcase.js'
import {
  loginViaCookies,
  preserveCookie,
} from '../../support/common/support.js'
import { verifyOrderInAdyen } from '../../support/adyen/adyen_apis.js'
import { loginToAdyen } from '../../support/adyen/testcase.js'

describe('Testing Adyen transaction API for full refund', () => {
  const singleProductEnvs = getTestVariables(singleProduct.prefix)
  const { orderIdEnv } = singleProductEnvs

  loginViaCookies()

  loginToAdyen()

  it('Verify whether we have an order to request for full refund', () => {
    cy.getOrderItems().then((order) => {
      if (!order[orderIdEnv]) {
        cy.qe('Order id missing in orders json')
        throw new Error('Order id is missing')
      } else {
        cy.qe('Order id found in orders json')
      }
    })
  })

  // Request full refund for the ordered product added in 2.2-singleProduct.spec.js
  refund(
    {
      total: singleProduct.getFullRefundTotal, // Amount
      title: 'full', // Refund Type for test case title
      env: orderIdEnv, // variable name where we stored the orderid in node environment
    },
    getRefundPayload,
    { startHandling: false }
  )

  verifyOrderInAdyen(singleProduct, singleProductEnvs, true)

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/shopper-location/2.2-test-locale-with-autoredirect.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { loginViaAPI, preserveCookie } from '../../support/common/support'
import { updateSettings } from '../../support/shopper-location/settings'
import {
  poland,
  location,
} from '../../support/shopper-location/outputvalidation'
import { addAddress } from '../../support/shopper-location/common'

const { country, url } = poland
const { lat, long } = location
const prefix = 'auto redirect configuration'

describe('Test Locale with Auto redirect', () => {
  loginViaAPI()

  updateSettings(country, url, { automaticRedirect: true })

  addAddress(prefix, { address: poland, lat, long })

  // eslint-disable-next-line jest/expect-expect
  it(`${prefix} - Now site should force redirect to google`, () => {
    cy.qe(
      'Without any popup the site will be automatically redirected to Google'
    )
    cy.url().should('eq', 'https://www.google.com/')
  })

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/shopper-location/wipe.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/valid-expect */
import { deleteAddresses } from '../../support/common/testcase.js'
import {
  loginViaCookies,
  preserveCookie,
} from '../../support/common/support.js'

describe('Wipe the pickup points', () => {
  loginViaCookies()

  deleteAddresses()

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/shopper-location/2.6-negative-scenarios-disable-location.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
import {
  loginViaAPI,
  preserveCookie,
  updateRetry,
} from '../../support/common/support'
import { verifyLocation } from '../../support/shopper-location/common'
import shopperLocationConstants from '../../support/shopper-location/constants'
import selectors from '../../support/common/selectors'

const prefix = 'Disable location'

describe('Location validation', () => {
  loginViaAPI()

  // eslint-disable-next-line jest/expect-expect
  it(`${prefix} - Test negative scenarios`, updateRetry(2), () => {
    verifyLocation()
    cy.qe(
      `Now we should see message as (${shopperLocationConstants.faildFindLocation}) in popup`
    )
    cy.get(selectors.AddressErrorContainer).should(
      'have.text',
      shopperLocationConstants.faildFindLocation
    )
  })

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/shopper-location/2.5-negative-scenarios-with-location.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { verifyLocation } from '../../support/shopper-location/common'
import {
  loginViaAPI,
  preserveCookie,
  updateRetry,
} from '../../support/common/support'
import shopperLocationConstants from '../../support/shopper-location/constants'
import selectors from '../../support/common/selectors'
import { location } from '../../support/shopper-location/outputvalidation'

const prefix = 'Enable location'

describe('Location validation', () => {
  loginViaAPI()

  // eslint-disable-next-line jest/expect-expect
  it(`${prefix} - Test negative scenarios`, updateRetry(2), () => {
    verifyLocation(location.lat, location.long)
    cy.qe(
      `Now we should see message as (${shopperLocationConstants.locationNotAvailable}) in popup`
    )
    cy.get(selectors.AddressErrorContainer).contains(
      shopperLocationConstants.locationNotAvailable
    )
    cy.get(selectors.countryDropdown).select('CAN')
    cy.qe('Type invalid postal code')
    cy.get(selectors.addressInputContainer).eq(0).type('000000')
    cy.qe(
      `Now user should see the ${shopperLocationConstants.invalidPostalCode} in popup"`
    )
    cy.get(selectors.ChangeLocationError).should(
      'have.text',
      shopperLocationConstants.invalidPostalCode
    )
  })

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/shopper-location/2.1-test-locale-redirect-configuration.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
import {
  loginViaAPI,
  preserveCookie,
  scroll,
  updateRetry,
} from '../../support/common/support'
import { updateSettings } from '../../support/shopper-location/settings'
import {
  poland,
  location,
} from '../../support/shopper-location/outputvalidation'
import selectors from '../../support/common/selectors.js'
import { addAddress } from '../../support/shopper-location/common'
import { syncCheckoutUICustom } from '../../support/common/testcase.js'

const { country, url } = poland
const { lat, long } = location

const prefix = 'Manual redirect configuration'

describe('Testing local redirect configuration', () => {
  loginViaAPI()

  syncCheckoutUICustom()

  updateSettings(country, url)

  addAddress(prefix, { address: poland, lat, long })

  // eslint-disable-next-line jest/expect-expect
  it(`${prefix} - Verify address`, updateRetry(2), () => {
    cy.qe(
      'After adding address, verifying it on Homepage address container whether the given address is showing'
    )
    scroll()
    cy.get(selectors.addressUpdation)
      .should('be.visible')
      .contains('Warsaw, mazowieckie, 00-014')
  })

  // eslint-disable-next-line jest/expect-expect
  it(`${prefix} - Get popup with switch button`, updateRetry(2), () => {
    cy.qe(
      'Once the address is verified, we will get an popup with visible of switch button. We should be able to click on the button.'
    )
    cy.get(selectors.ToastMsgInB2B).should('be.visible', { timeout: 10000 })
    cy.get(selectors.switchButton).should('be.visible').click()
  })

  // eslint-disable-next-line jest/expect-expect
  it(`${prefix} - Page will be redirected to google page`, () => {
    cy.qe(
      'Once manually switch popup link is clicked, it should redirect us to Google'
    )
    cy.url().should('eq', 'https://www.google.com/')
  })

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/shopper-location/2.3-disable-location-via-browser-popup-order-product.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { loginViaAPI, preserveCookie } from '../../support/common/support'
import { orderProductTestCase } from '../../support/shopper-location/common'
import { UsDetails } from '../../support/shopper-location/outputvalidation'

const prefix = 'Disable location'

describe(`${prefix}- via browser popup - Order the Product`, () => {
  loginViaAPI()

  orderProductTestCase(prefix, UsDetails)

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/shopper-location/2.4-enable-Location-via-browser-popup-order-product.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { loginViaAPI, preserveCookie } from '../../support/common/support'
import { orderProductTestCase } from '../../support/shopper-location/common'
import { UsDetails } from '../../support/shopper-location/outputvalidation'

const prefix = 'Enable location'

describe(`${prefix}- via browser popup - Order the Product`, () => {
  loginViaAPI()

  orderProductTestCase(prefix, UsDetails)

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/fedex-shipping/2.10-validate-surcharge-flat-rate.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/valid-expect */
/* eslint-disable jest/valid-expect-in-promise */
/* eslint-disable jest/expect-expect */
import { updateRetry, loginViaCookies } from '../../support/common/support'
import { appSetting } from '../../support/fedex-shipping/outputvalidation'
import { data } from '../../fixtures/fedex-shipping-fixtures/shippingRatePayload.json'
import { updateSLASettings } from '../../support/fedex-shipping/common.js'
import {
  loadCalculateShippingAPI,
  validateCalculateShipping,
} from '../../support/fedex-shipping/api_testcase'

const prefix = 'Shipping Optimize'
let shippingMethods = []
const surchargeFlatRate = 20
const surchargePercent = 0

describe('Modify SLA - Validate Surcharge Flat Rate in checkout', () => {
  loginViaCookies()

  it(`${prefix} - Update Surcharge Flat Rate`, updateRetry(3), () => {
    updateSLASettings(appSetting)
  })

  it(`${prefix} - Verify shipping price`, updateRetry(3), () => {
    loadCalculateShippingAPI(data).then((response) => {
      validateCalculateShipping(response)
      shippingMethods = response.body
    })
  })

  it(` ${prefix} - Update Surcharge Flat Rate`, updateRetry(3), () => {
    updateSLASettings(appSetting, surchargeFlatRate, surchargePercent)
  })

  it(`${prefix} - Validate Surcharge Flat Rate Changes`, updateRetry(3), () => {
    loadCalculateShippingAPI(data).then((response) => {
      validateCalculateShipping(response)

      shippingMethods.forEach((shippingMethod) => {
        response.body.forEach((res) => {
          // eslint-disable-next-line vtex/prefer-early-return
          if (res.shippingMethod === shippingMethod.shippingMethod) {
            const calculateFlatRate = shippingMethod.price + surchargeFlatRate

            // eslint-disable-next-line jest/no-conditional-expect
            expect(parseFloat(res.price.toFixed(2))).to.equal(calculateFlatRate)
          }
        })
      })
    })
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/fedex-shipping/2.3-single-product-scenarios.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/no-conditional-expect */
/* eslint-disable jest/expect-expect */
/* eslint-disable jest/valid-expect */
/* eslint-disable jest/valid-expect-in-promise */
import { loginViaCookies, updateRetry } from '../../support/common/support.js'
import {
  singleProduct,
  warehouseId,
} from '../../support/fedex-shipping/outputvalidation.js'
import { data } from '../../fixtures/fedex-shipping-fixtures/shippingRatePayload.json'
import {
  loadCalculateShippingAPI,
  validateCalculateShipping,
} from '../../support/fedex-shipping/api_testcase.js'
import {
  verifyInventoryIsUnlimitedForFedexWareHouse,
  validateInventory,
} from '../../support/fedex-shipping/graphql_testcase.js'
import { INVENTORY_GRAPHQL_APP } from '../../support/fedex-shipping/graphql_apps.js'
import { graphql } from '../../support/common/graphql_utils'

const { prefix } = singleProduct
let shippingMethods = []

describe(`${prefix} Scenarios`, () => {
  loginViaCookies()

  it(`${prefix} - For fedex docks, verify inventory is set to infinite`, () => {
    graphql(
      INVENTORY_GRAPHQL_APP,
      verifyInventoryIsUnlimitedForFedexWareHouse(
        warehouseId,
        data.items[0].id
      ),
      validateInventory
    )
  })

  it(`${prefix} - Verify single product shipping price`, updateRetry(3), () => {
    loadCalculateShippingAPI(data).then((response) => {
      validateCalculateShipping(response)
      shippingMethods = response.body
    })
  })

  it(
    `${prefix} - Set product quantity to 2 and verify shipping price via API`,
    updateRetry(3),
    () => {
      data.items[0].quantity = 2
      loadCalculateShippingAPI(data).then((response) => {
        validateCalculateShipping(response)
        shippingMethods.forEach((shippingMethod) => {
          response.body.forEach((res) => {
            if (res.shippingMethod === shippingMethod.shippingMethod) {
              expect(shippingMethod.shippingMethod).to.equal(res.shippingMethod)

              expect(parseFloat(res.price.toFixed(2))).to.equal(
                shippingMethod.price * 2
              )
            }
          })
        })
      })
    }
  )
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/fedex-shipping/2.5-hide-sla-scenarios.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/valid-expect */
/* eslint-disable jest/valid-expect-in-promise */
/* eslint-disable jest/expect-expect */
import { updateRetry, loginViaCookies } from '../../support/common/support'
import { appSetting } from '../../support/fedex-shipping/outputvalidation'
import { FEDEX_SHIPPING_APP } from '../../support/fedex-shipping/graphql_apps.js'
import {
  saveAppSetting,
  validateSaveAppSettingResponse,
} from '../../support/fedex-shipping/graphql_testcase.js'
import { data } from '../../fixtures/fedex-shipping-fixtures/shippingRatePayload.json'
import { loadCalculateShippingAPI } from '../../support/fedex-shipping/api_testcase.js'
import { graphql } from '../../support/common/graphql_utils'

const prefix = 'Hide Sla'

describe('FedEx Hide sla scenarios', () => {
  loginViaCookies()

  it(`${prefix} - Hide all Sla's`, updateRetry(3), () => {
    cy.qe('Update sla to hide using saveAppSetting graphql')
    cy.hideSla(true).then((sla) => {
      graphql(
        FEDEX_SHIPPING_APP,
        saveAppSetting(appSetting, sla),
        validateSaveAppSettingResponse
      )
    })
  })

  it(`${prefix} - Verify all sla's are not displaying`, updateRetry(2), () => {
    loadCalculateShippingAPI(data).then((response) => {
      expect(response.status).to.have.equal(200)
      expect(response.body).to.be.an('array').and.to.have.lengthOf(0)
    })
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/fedex-shipping/2.7-enable-disable-ship-to-residential-toggle.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/valid-expect */
/* eslint-disable jest/valid-expect-in-promise */
import { loginViaCookies, updateRetry } from '../../support/common/support.js'
import {
  saveAppSetting,
  validateSaveAppSettingResponse,
} from '../../support/fedex-shipping/graphql_testcase.js'
import { graphql } from '../../support/common/graphql_utils'
import { appSetting } from '../../support/fedex-shipping/outputvalidation.js'
import { data } from '../../fixtures/fedex-shipping-fixtures/shippingRatePayload.json'
import {
  loadCalculateShippingAPI,
  validateCalculateShipping,
} from '../../support/fedex-shipping/api_testcase.js'
import { FEDEX_SHIPPING_APP } from '../../support/fedex-shipping/graphql_apps.js'
import sla from '../../support/fedex-shipping/sla.js'

const prefix = 'Ship To Residential'

describe(`${prefix} Scenarios`, () => {
  loginViaCookies()

  it(`${prefix} - Disable Ship to Residential`, updateRetry(3), () => {
    appSetting.residential = false
    cy.readSlaSettings().then((sl) => {
      graphql(
        FEDEX_SHIPPING_APP,
        saveAppSetting(appSetting, sl),
        validateSaveAppSettingResponse
      )
    })
    loadCalculateShippingAPI(data).then((response) => {
      validateCalculateShipping(response)
      const filtershippingMethod = response.body.filter(
        (b) => b.shippingMethod === sla.FedexGroundDelivery
      )

      expect(filtershippingMethod)
        .to.be.an('array')
        .and.to.have.lengthOf.above(0)
    })
  })

  it(`${prefix} - Enable Ship to Residential`, updateRetry(3), () => {
    appSetting.residential = true
    cy.readSlaSettings().then((s) => {
      graphql(
        FEDEX_SHIPPING_APP,
        saveAppSetting(appSetting, s),
        validateSaveAppSettingResponse
      )
    })
    loadCalculateShippingAPI(data).then((response) => {
      validateCalculateShipping(response)
      const filtershippingMethod = response.body.filter(
        (b) => b.shippingMethod === sla.FedexHomeDelivery
      )

      expect(filtershippingMethod)
        .to.be.an('array')
        .and.to.have.lengthOf.above(0)
    })
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/fedex-shipping/2.2-rest-apis.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/expect-expect */
import {
  loginViaCookies,
  preserveCookie,
  updateRetry,
} from '../../support/common/support.js'
import {
  loadDocks,
  loadCalculateShippingAPI,
  validateCalculateShipping,
} from '../../support/fedex-shipping/api_testcase.js'
import { data } from '../../fixtures/fedex-shipping-fixtures/shippingRatePayload.json'

const prefix = 'Rest API'

describe('Rest-api-testcases', () => {
  loginViaCookies()

  loadDocks()

  it(`${prefix} - Calculate shipping price`, updateRetry(2), () => {
    loadCalculateShippingAPI(data, validateCalculateShipping)
  })

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/fedex-shipping/2.8-shipping-optimize-scenarios.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/valid-expect */
/* eslint-disable jest/valid-expect-in-promise */
/* eslint-disable jest/expect-expect */
import { loginViaCookies, updateRetry } from '../../support/common/support.js'
import {
  saveAppSetting,
  savePackingOptimizationAppSetting,
  validateSaveAppSettingResponse,
} from '../../support/fedex-shipping/graphql_testcase.js'
import {
  appSetting,
  smartPackingAccessKey,
  packingOptimizationSettings,
} from '../../support/fedex-shipping/outputvalidation.js'
import { data } from '../../fixtures/fedex-shipping-fixtures/shippingOptimizePayload.json'
import {
  loadCalculateShippingAPI,
  validateCalculateShipping,
} from '../../support/fedex-shipping/api_testcase.js'
import {
  FEDEX_SHIPPING_APP,
  PACKING_OPTIMIZATION,
} from '../../support/fedex-shipping/graphql_apps.js'
import sla from '../../support/fedex-shipping/sla.js'
import { graphql } from '../../support/common/graphql_utils.js'

const prefix = 'Shipping Optimize'
let NonePackingShippingPrice = ''
let PackAllInOneShippingPrice = ''
let SmartPackingShippingPrice = ''

describe(`${prefix} Scenarios`, () => {
  loginViaCookies()

  it(`${prefix} - Generate access key`, updateRetry(2), () => {
    graphql(
      PACKING_OPTIMIZATION,
      savePackingOptimizationAppSetting(packingOptimizationSettings),
      validateSaveAppSettingResponse
    )
  })

  it(
    `${prefix} - Select shipping optimize type None and validate`,
    updateRetry(3),
    () => {
      appSetting.optimizeShippingType = 0 // Update shipping type to None

      cy.readSlaSettings().then((sl) => {
        graphql(
          FEDEX_SHIPPING_APP,
          saveAppSetting(appSetting, sl),
          validateSaveAppSettingResponse
        )
      })
      cy.addDelayBetweenRetries(10000)
      loadCalculateShippingAPI(data).then((response) => {
        validateCalculateShipping(response)
        const filtershippingMethod = response.body.filter(
          (b) =>
            b.shippingMethod === sla.FirstOvernight ||
            b.shippingMethod === sla.StandardOvernight
        )

        expect(filtershippingMethod)
          .to.be.an('array')
          .and.to.have.lengthOf.above(0)
        NonePackingShippingPrice = filtershippingMethod[0].price
      })
    }
  )

  it(
    `${prefix} - Select shipping optiomize type Pack All In One and validate`,
    updateRetry(3),
    () => {
      appSetting.optimizeShippingType = 1 // Update shipping type to Pack all in one

      cy.readSlaSettings().then((getSla) => {
        graphql(
          FEDEX_SHIPPING_APP,
          saveAppSetting(appSetting, getSla),
          validateSaveAppSettingResponse
        )
      })
      cy.addDelayBetweenRetries(10000)
      loadCalculateShippingAPI(data).then((response) => {
        validateCalculateShipping(response)
        const filtershippingMethod = response.body.filter(
          (b) =>
            b.shippingMethod === sla.FirstOvernight ||
            b.shippingMethod === sla.StandardOvernight
        )

        expect(filtershippingMethod)
          .to.be.an('array')
          .and.to.have.lengthOf.above(0)
        PackAllInOneShippingPrice = filtershippingMethod[0].price
      })
    }
  )

  it(
    `${prefix} - Select shipping optiomize type Smart Packing and validate`,
    updateRetry(3),
    () => {
      appSetting.optimizeShippingType = 2 // Update shipping type to Smart Packing
      appSetting.packingAccessKey = smartPackingAccessKey // Add Smart Packing Access Key

      cy.readSlaSettings().then((s) => {
        // update settings
        graphql(
          FEDEX_SHIPPING_APP,
          saveAppSetting(appSetting, s),
          validateSaveAppSettingResponse
        )
      })
      cy.addDelayBetweenRetries(10000)
      loadCalculateShippingAPI(data).then((response) => {
        validateCalculateShipping(response)
        const filtershippingMethod = response.body.filter(
          (b) =>
            b.shippingMethod === sla.FirstOvernight ||
            b.shippingMethod === sla.StandardOvernight
        )

        expect(filtershippingMethod)
          .to.be.an('array')
          .and.to.have.lengthOf.above(0)
        SmartPackingShippingPrice = filtershippingMethod[0].price
      })
    }
  )

  it(
    `${prefix} - Verify None shipping price is higher than Pack all in one box and Smart packing`,
    updateRetry(1),
    () => {
      expect(NonePackingShippingPrice).to.be.gt(PackAllInOneShippingPrice)
      expect(NonePackingShippingPrice).to.be.gt(SmartPackingShippingPrice)
    }
  )

  it(
    `${prefix} - Verify Pack all in one box shipping price is higher than None`,
    updateRetry(1),
    () => {
      expect(PackAllInOneShippingPrice).to.be.lt(NonePackingShippingPrice)
    }
  )

  it(
    `${prefix} - Verify Smart Packig shipping price is higher than None`,
    updateRetry(1),
    () => {
      expect(SmartPackingShippingPrice).to.be.lt(NonePackingShippingPrice)
      expect(SmartPackingShippingPrice).to.be.lte(PackAllInOneShippingPrice)
    }
  )
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/fedex-shipping/2.6-show-sla-scenarios.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/expect-expect */
/* eslint-disable jest/valid-expect */
import { updateRetry, loginViaCookies } from '../../support/common/support.js'
import { appSetting } from '../../support/fedex-shipping/outputvalidation.js'
import { FEDEX_SHIPPING_APP } from '../../support/fedex-shipping/graphql_apps.js'
import {
  saveAppSetting,
  validateSaveAppSettingResponse,
} from '../../support/fedex-shipping/graphql_testcase.js'
import { graphql } from '../../support/common/graphql_utils'
import { data } from '../../fixtures/fedex-shipping-fixtures/shippingRatePayload.json'
import {
  loadCalculateShippingAPI,
  validateCalculateShipping,
} from '../../support/fedex-shipping/api_testcase.js'

const prefix = `UnHide sla`

describe('FedEx UnHide sla scenarios', () => {
  loginViaCookies()

  it(`${prefix} - Unhide all sla's`, updateRetry(3), () => {
    cy.qe('Update sla to show using saveAppSetting graphql')
    cy.hideSla(false).then((sla) => {
      graphql(
        FEDEX_SHIPPING_APP,
        saveAppSetting(appSetting, sla),
        validateSaveAppSettingResponse
      )
    })
  })

  it(`${prefix} - Calculate shipping price`, updateRetry(2), () => {
    loadCalculateShippingAPI(data, validateCalculateShipping)
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/fedex-shipping/2.11-validate-surcharge-percentage.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/valid-expect */
/* eslint-disable jest/expect-expect */
/* eslint-disable jest/valid-expect-in-promise */
import { updateRetry, loginViaCookies } from '../../support/common/support'
import { appSetting } from '../../support/fedex-shipping/outputvalidation'
import { data } from '../../fixtures/fedex-shipping-fixtures/shippingRatePayload.json'
import { updateSLASettings } from '../../support/fedex-shipping/common.js'
import {
  loadCalculateShippingAPI,
  validateCalculateShipping,
} from '../../support/fedex-shipping/api_testcase'

const prefix = 'Shipping Optimize'
let shippingMethods = []
const surchargeFlatRate = 0
const surchargePercent = 30

describe('Modify SLA - Validate Surcharge Percentage in checkout', () => {
  loginViaCookies()

  it(`${prefix} - Update Surcharge Flat Rate`, updateRetry(3), () => {
    updateSLASettings(appSetting)
  })

  it(`${prefix} - Verify shipping price`, updateRetry(3), () => {
    loadCalculateShippingAPI(data).then((response) => {
      validateCalculateShipping(response)
      shippingMethods = response.body
    })
  })

  it(` ${prefix} - Update Surcharge percentage`, updateRetry(3), () => {
    updateSLASettings(appSetting, surchargeFlatRate, surchargePercent)
  })

  it(
    `${prefix} - Validate Surcharge Percentage Changes`,
    updateRetry(3),
    () => {
      // eslint-disable-next-line jest/valid-expect-in-promise
      loadCalculateShippingAPI(data).then((response) => {
        validateCalculateShipping(response)

        shippingMethods.forEach((shippingMethod) => {
          response.body.forEach((res) => {
            // eslint-disable-next-line vtex/prefer-early-return
            if (res.shippingMethod === shippingMethod.shippingMethod) {
              const calculatePercentage =
                (shippingMethod.price * surchargePercent) / 100

              const calculateFlatRate = shippingMethod.price + surchargeFlatRate

              // eslint-disable-next-line jest/no-conditional-expect
              expect(parseFloat(res.price.toFixed(2))).to.equal(
                parseFloat((calculatePercentage + calculateFlatRate).toFixed(2))
              )
            }
          })
        })
      })
    }
  )
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/fedex-shipping/2.12-surcharge-flat-rate-and-surcharge-percentage.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/no-conditional-expect */
/* eslint-disable jest/valid-expect */
/* eslint-disable jest/valid-expect-in-promise */
/* eslint-disable jest/expect-expect */
import { loginViaCookies, updateRetry } from '../../support/common/support.js'
import { appSetting } from '../../support/fedex-shipping/outputvalidation'
import { data } from '../../fixtures/fedex-shipping-fixtures/shippingRatePayload.json'
import { updateSLASettings } from '../../support/fedex-shipping/common.js'
import {
  loadCalculateShippingAPI,
  validateCalculateShipping,
} from '../../support/fedex-shipping/api_testcase.js'

const prefix = 'Update SLA - Surcharge Flat Rate & Surcharge Percentage'
let shippingMethods = []
const surchargeFlatRate = 10
const surchargePercent = 15

describe(`${prefix} Scenarios`, () => {
  loginViaCookies()

  it(
    `${prefix} - Update Surcharge Flat Rate and Surcharge Percentage`,
    updateRetry(3),
    () => {
      updateSLASettings(appSetting)
    }
  )

  it(`${prefix} - Verify single product shipping price`, updateRetry(3), () => {
    loadCalculateShippingAPI(data).then((response) => {
      validateCalculateShipping(response)
      shippingMethods = response.body
    })
  })

  it(
    ` ${prefix} - Update Surcharge Flat Rate and Surcharge Percentage`,
    updateRetry(3),
    () => {
      updateSLASettings(appSetting, surchargeFlatRate, surchargePercent)
    }
  )

  it(`${prefix} - Validate Surcharge Changes`, updateRetry(3), () => {
    loadCalculateShippingAPI(data).then((response) => {
      validateCalculateShipping(response)

      shippingMethods.forEach((shippingMethod) => {
        response.body.forEach((res) => {
          // eslint-disable-next-line vtex/prefer-early-return
          if (res.shippingMethod === shippingMethod.shippingMethod) {
            const percentage = (shippingMethod.price * surchargePercent) / 100
            const rate = shippingMethod.price + surchargeFlatRate
            const total = percentage + rate

            expect(parseFloat(res.price.toFixed(2))).to.equal(
              parseFloat(total.toFixed(2))
            )
          }
        })
      })
    })
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/fedex-shipping/2.13-verify-fedex-supported-non-supported-countries.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/no-disabled-tests */
/* eslint-disable jest/expect-expect */
import {
  updateRetry,
  loginViaCookies,
  preserveCookie,
} from '../../support/common/support.js'
import { data } from '../../fixtures/fedex-shipping-fixtures/shippingRatePayload.json'
import {
  loadCalculateShippingAPI,
  validateCalculateShipping,
  validateCustomDeliveryTime,
  validateNonSupportedCountryCalculateShipping,
} from '../../support/fedex-shipping/api_testcase.js'

describe('Verify fedex shipping price for Kuwait and verify custom delivery time', () => {
  loginViaCookies()

  it(
    `Verify shipping price for fedex supported country Kuwait`,
    updateRetry(5),
    () => {
      data.destination.city = 'Kuwait City'
      data.destination.country = 'KWT'
      data.destination.zipCode = '72303'
      loadCalculateShippingAPI(data, validateCalculateShipping)
    }
  )

  it(
    `Verify shipping price for fedex non supported country India`,
    updateRetry(5),
    () => {
      data.destination.state = 'TamilNadu'
      data.destination.city = 'Chennai'
      data.destination.country = 'IND'
      data.destination.zipCode = '600079'
      loadCalculateShippingAPI(
        data,
        validateNonSupportedCountryCalculateShipping
      )
    }
  )

  it(`Verify custom delivery time`, updateRetry(4), () => {
    data.destination.state = null
    data.destination.city = null
    data.destination.zipCode = '00010002'
    data.destination.country = 'USA'
    loadCalculateShippingAPI(data, validateCustomDeliveryTime)
  })

  preserveCookie()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of cy-runner/cypress-shared/integration/fedex-shipping/2.4-multi-product-scenarios.spec.js from the cy-runner VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable jest/no-conditional-expect */
/* eslint-disable jest/expect-expect */
/* eslint-disable jest/valid-expect */
/* eslint-disable jest/valid-expect-in-promise */
import { loginViaCookies, updateRetry } from '../../support/common/support.js'
import { multiProduct } from '../../support/fedex-shipping/outputvalidation.js'
import { data } from '../../fixtures/fedex-shipping-fixtures/multiProductPayload.json'
import {
  loadCalculateShippingAPI,
  validateCalculateShipping,
} from '../../support/fedex-shipping/api_testcase.js'

const { prefix } = multiProduct
let shippingMethods = []

describe(`${prefix} Scenarios`, () => {
  loginViaCookies()

  it(`${prefix} - Verify multi product shipping price`, updateRetry(3), () => {
    loadCalculateShippingAPI(data).then((response) => {
      validateCalculateShipping(response)
      shippingMethods = response.body
    })
  })

  it(
    `${prefix} - Set product quantity to 2 and verify shipping price via API`,
    updateRetry(3),
    () => {
      data.items[1].quantity = 2
      loadCalculateShippingAPI(data).then((response) => {
        validateCalculateShipping(response)
        shippingMethods.forEach((shippingMethod) => {
          response.body.forEach((res) => {
            if (
              res.shippingMethod === shippingMethod.shippingMethod &&
              res.numberOfPackages === 2
            ) {
              expect(shippingMethod.shippingMethod).to.equal(res.shippingMethod)

              expect(parseFloat(res.price.toFixed(2))).to.equal(
                shippingMethod.price * 2
              )
            }
          })
        })
      })
    }
  )
})

```