Kakali Mahapatra
Kakali Mahapatra

Reputation: 1

How to force cy.writeFile() before cy.intercept()

I want to update the time in my fixture to the current time every time before running tests and feed that fixture file with the updated time as a response in the cy.intercept(). But every time cy.intercept() loads data from the original file (Not with the updated time) and then writes the fixture file with the updated time.

How do I make sure that the fixture file is updated first and then intercept call?

describe('NBA pregame EventTile verification', () => {

  beforeEach('Enforce game start time', function () {

    // Function to read and update schedule file, returning a promise
    const updateSchedule = (filePath, updateCallback) => {
      return cy.fixture(filePath).then((nbaData) => {
        updateCallback(nbaData);
        return cy.writeFile(filePath, nbaData);
      });
    };

    // Update QB schedule and set up interception
    const updateQBAndIntercept = () => {
      return updateSchedule('Odds/QB/NBA1Schedule.json', (nbaData) => {
        const nbaGame = nbaData.NBA[0];
        const currentTimestamp = Date.now();
        const adjustedStartTime = currentTimestamp + (2 * 60 * 60 * 1000); // 2 hours ahead
        nbaGame.startTime = adjustedStartTime;
      }).then(() => {
        return cy.intercept('GET', '**/quarterback/lighterGames/leagues/**', {
          fixture: 'Odds/QB/NBA1Schedule.json'
        }).as('nbaPregameqb');
      });
    };

    // Update DK schedule and set up interception
    const updateDKAndIntercept = () => {
      return updateSchedule('Odds/DK/NBA1Schedule.json', (nbaData) => {
        const nbaGame = nbaData.NBA[0];
        const currentDate = new Date();
        const adjustedStartDate = new Date(currentDate.getTime() + (2 * 60 * 60 * 1000)); // 2 hours ahead
        nbaGame.startDate = adjustedStartDate.toISOString();
      }).then(() => {
        return cy.intercept('GET', '**/sports-oddsapp-offers.xreapps.net/dk/events/**', {
          fixture: 'Odds/DK/NBA1Schedule.json'
        }).as('nbaPregamedk');
      });
    };

    cy.intercept('GET', '**/quarterback/lighterGame/league/**', {
      fixture: 'Odds/QB/NBA1Details.json'
    }).as('nbaPregameDetailqb');

    cy.intercept('GET', '**/sports-oddsapp-offers.xreapps.net/dk/props,lines/**', {
      fixture: 'Odds/DK/NBA1Details.json'
    }).as('nbaPregameDetaildk');

    // Launch the Odds App and wait for intercepts to be set up
    const launchAppAndWaitForIntercepts = () => {
      cy.launchOddsApp();
      return cy.wait(['@nbaPregameqb', '@nbaPregamedk']);
    };

    // Chain the promises to ensure sequential execution
    updateQBAndIntercept()
      .then(updateDKAndIntercept)
      .then(launchAppAndWaitForIntercepts);
  })

  context('Odds Explorer Page', () => {

    it.only('Should have NBA pregame Tile', () => {

Upvotes: 0

Views: 107

Answers (1)

Frida.Ingvarsdottir
Frida.Ingvarsdottir

Reputation: 173

It's most likely the fault of using cy.fixture() caching.

See How to ... fetch the newly updated value in testdata.json

Please keep in mind that fixture files are assumed to be unchanged during the test, and thus Cypress loads them just once. Even if you overwrite the fixture file itself, the already loaded fixture data remains the same.

If you wish to dynamically change the contents of a file during your tests, consider cy.readFile() instead.

Use a custom command to expand the intercept, using routeHandler function, and provide an expanded filePath.

Using the routeHandler function

Function to expand filePath

const pathTofixture = (filePath)  => `cypress/fixtures/${filePath}`;

Command to intercept with no fixture caching

Cypress.Commands.add('interceptNC', ({url, file, alias}) => {
  return cy.intercept(url, (req) => {
    cy.readFile(pathToFixture(file)).then(data => req.reply(data)) 
  }).as(alias)
}
// Function to read and update schedule file, returning a promise
const updateSchedule = (filePath, updateCallback) => {
  return cy.readFile(pathToFixture(filePath)).then((nbaData) => {
    updateCallback(nbaData);
    return cy.writeFile(pathToFixture(filePath), nbaData);
  });
}

// Update QB schedule and set up interception
const updateQBAndIntercept = () => {
  return updateSchedule('Odds/QB/NBA1Schedule.json', (nbaData) => {
    ...
  }).then(() => {
    cy.interceptNC({
      url:   '**/quarterback/lighterGames/leagues/**', 
      file:  'Odds/QB/NBA1Schedule.json',
      alias: 'nbaPregameqb'
    })
  });
}

// Update DK schedule and set up interception
const updateDKAndIntercept = () => {
  return updateSchedule('Odds/DK/NBA1Schedule.json', (nbaData) => {
    ...
  }).then(() => {
    cy.interceptNC({
      url:   '**/sports-oddsapp-offers.xreapps.net/dk/events/**', 
      file:  'Odds/DK/NBA1Schedule.json',
      alias: 'nbaPregamedk'
    })
  });
};

cy.interceptNC({
  url:   '**/quarterback/lighterGame/league/**', 
  file:  'Odds/QB/NBA1Details.json',
  alias: 'nbaPregameDetailqb'
})

cy.interceptNC({
  url:   '**/sports-oddsapp-offers.xreapps.net/dk/props,lines/**', 
  file:  'Odds/DK/NBA1Details.json',
  alias: 'nbaPregameDetaildk'
})

...

Skipping writeFile()

If you only need the +2 hours for the intercept, you can skip cy.writeFile() by passing the modified data directly to the intercept.

Cypress.Commands.add('interceptPlusTwoHours', ({url, filePath, alias}) => {

  cy.fixture(filePath).then((nbaData) => {
    const nbaGame = nbaData.NBA[0];
    const currentTimestamp = Date.now();
    const adjustedStartTime = currentTimestamp + (2 * 60 * 60 * 1000); // 2 hours ahead
    nbaGame.startTime = adjustedStartTime;

    cy.intercept(url, (req) => {
      req.reply(nbaData)
    })
    .as(alias)
  })
})

// Update QB schedule and set up interception
const updateQBAndIntercept = () => {
  cy.interceptPlusTwoHours({
    filePath: 'Odds/QB/NBA1Schedule.json',
    url:      '**/quarterback/lighterGames/leagues/**',
    alias:    'nbaPregameqb'
  })
}

// etc

Upvotes: 6

Related Questions