Cash register: My code does what tests ask to do but it doesn't pass them

const changeDue = document.getElementById('change-due');
const screenPrice = document.getElementById('price');
const cashInput = document.getElementById('cash');
const purchaseBtn = document.getElementById('purchase-btn');
const moneyDrawer = document.querySelectorAll('.money');
const openDrawerBtn = document.getElementById('open-drawer-btn');
const cashDrawer = document.getElementById('cash-drawer');

let price = 19.50;
let cid = [
  ['PENNY', 0.5],
  ['NICKEL', 0],
  ['DIME', 0],
  ['QUARTER', 0],
  ['ONE', 0],
  ['FIVE', 0],
  ['TEN', 0],
  ['TWENTY', 0],
  ['ONE HUNDRED', 0]
];

screenPrice.value = price;
let totalCid = 0

// Total cid update
const totalCidUpdate = () => {
  totalCid = cid.reduce((acc, value) => {
    return acc += value[1]
  },0)
}
 totalCidUpdate();

// Cash register drawer display
let drawerOpen = false;
const openDrawer = () => {
  if(drawerOpen) {
    cashDrawer.style.display = 'none';
    drawerOpen = false;
  } else {
    cashDrawer.style.display = 'grid';
    drawerOpen = true; 
  }
};

// Cash register drawer update
const drawerDisplay = () => {
  cid.forEach((value, index) => {
    moneyDrawer[index].innerText = (value[1]).toFixed(2)
  })
};
drawerDisplay();

// Change calculation, Change Due Messages and Status display
const changeCalc = () => {
  const cash = parseFloat(cashInput.value)
  let change = parseFloat((cash - price).toFixed(2))
  let reversedCid = [...cid].reverse();
  const denominations = [100, 20, 10, 5, 1, 0.25, 0.10, 0.05, 0.01];

  if(cash < price) {
    alert('Customer does not have enough money to purchase the item')
    changeDue.style.display = 'none';
    return
  } else if(cash === price) {
    changeDue.style.display = 'block';
    changeDue.innerText = 'No change due - customer paid with exact cash \n'
    return
  } else {
    if(change > totalCid) {
      changeDue.style.display = 'block';
      changeDue.innerText = 'Status: INSUFFICIENT_FUNDS \n'
      return
    } else if(change === totalCid) {
      changeDue.style.display = 'block';
      changeDue.innerText = 'Status: CLOSED \n'
    } else {
      changeDue.style.display = 'block';
      changeDue.innerText = 'Status: OPEN \n'
    }
  }

  for (let i = 0; i <= reversedCid.length - 1; i++) {
    const denominationNum = Math.floor(change / denominations[i]);
    const denominationAmount = Math.min(denominationNum * denominations[i], reversedCid[i][1]);

    change -= denominationAmount;
    change = parseFloat(change.toFixed(2));
    const originalIndex = cid.length - 1 - i;
    cid[originalIndex][1] -= denominationAmount;

    if(denominationAmount > 0){
      changeDue.innerText += ` ${cid[originalIndex][0]}: $${denominationAmount} \n`
    }
    totalCidUpdate();
    drawerDisplay();
    }

  if(change > 0) {
      changeDue.style.display = 'block';
      changeDue.innerText = `Status: INSUFFICIENT_FUNDS \n`
    }
}

openDrawerBtn.addEventListener('click', () => openDrawer());
purchaseBtn.addEventListener('click', () => {
  changeCalc();
})

The main problem is with these two. But at some point, randomly, it fails to pass another test.

You should get rid of these global variables

The code above should not be in the global scope. You should put it inside the function that runs when purchase is called.

(The testcases run in sequence and the page is not reloaded in between so these statements do not run except once at the start of the first testcase and never again)