#498·pollyjs

[Bug] Polly replays weird array type from persisted file (replayedData instanceof Array returns false)

Author: tomasz-szymanekCreated Jun 27, 2024Updated Jun 27, 2024

Description

Polly replays weird array type from persisted file (replayedData instanceof Array returns false)

Shareable Source

In regular API call:

javascript
console.log(response.hits.hits instanceof Array)
// true

const slidesCamelized = response.hits.hits.map((el) => camelize(el._source)) as Slide[]

  const productsIds = slidesCamelized
    .filter((el) => el.productId !== null)
    .map((element) => element.productId) as number[]
    
// some operations so we know that map and filter work in this type

console.log(productsIds instanceof Array)
// true
console.log(productsIds.constructor.prototype)
// Object(0) []
console.log(Array.constructor.prototype)
// {}

but when invoked in tests while replaying using Polly:

javascript
console.log(response.hits.hits instanceof Array)
// false

// ...

console.log(productsIds instanceof Array)
// false
console.log(productsIds.constructor.prototype)
// Object(0) []
console.log(Array.constructor.prototype)
// {}

Error Message & Stack Trace

Why this is an issue? Because Elastic query builder validates termsQuery method using instanceof Array. This makes all elasticsearch queries (that were built using data from persisted polly records and termsQuery) fail.

Config

I am using @pollyjs/adapter-fetch due to Node 18 on our project. Also, it's worth to mention that node-http adapter doesn't work with native http from core node. I had to write my own Elastic Client library to use Polly with.

Copy the config used to setup the Polly instance:

javascript
/** @jest-environment setup-polly-jest/jest-environment-node */
import * as path from 'path'
import { MODES } from '@pollyjs/utils'
import { setupPolly } from 'setup-polly-jest'

export const startPolly = () =>
  setupPolly({
    mode: MODES.REPLAY,
    recordIfMissing: process.env.POLLY_RECORD || true,
    adapters: [require('@pollyjs/adapter-fetch')],
    persister: require('@pollyjs/persister-fs'),
    persisterOptions: {
      fs: {
        recordingsDir: path.resolve(__dirname, './recordings'),
      },
    },
    matchRequestsBy: {
      method: true,
      headers: true,
      body: true,
      order: false,
      url: {
        protocol: true,
        username: false,
        password: false,
        hostname: true,
        port: false,
        pathname: true,
        query: true,
        hash: true,
      },
    },
  })

Dependencies

Copy the @pollyjs dependencies from package.json:

json
{
 "@pollyjs/adapter-fetch": "^6.0.6",
 "@pollyjs/core": "^6.0.6",
 "@pollyjs/persister-fs": "^6.0.6",
}

Relevant Links

Environment

I am using superTest, jest for testing and express for API