'In TestCafe, is there a way to run an assertion that passes if the selector matches if 1 of 2 possible values?

Right now have I a test with an assertion that checks for today's date. However, because of time zone issues, it will start failing at a certain time of day, because the report correctly shows "tomorrow's" date while TestCafe is looking for what it has as today's date.

Basically, I would like to write an assertion that passes if it shows either today or tomorrow's date, but fail for all other values.

Is there a way to write an assertion that checks for 1 of 2 values? Is there some way to use an OR operator in an assertion?

Something along the lines of:

await t
    .expect(Site.reportValues.reportHeaderInfo.innerText)
    .contains({ todaysDate || tomorrowsDate }, 
    "Report header should show either today's date or tomorrow's date",
    );


Solution 1:[1]

I don't think this is possible. But you can do this in JS (in multiple ways, I show one, you might find a better one):

function getTodayWithOffset(offset = 0) {
    let today = new Date();
    today.setDate(today.getDate() + offset);
    return today;
}

function isTodayOrTomorrow(date) {
    return [getTodayWithOffset().toLocaleDateString(), getTodayWithOffset(1).toLocaleDateString()]
        .filter(d => d === date.toLocaleDateString())
        .length === 1;
}

const headerDateText = await Selector(Site.reportValues.reportHeaderInfo).innerText;
const headerDate = new Date(headerDateText); // this might be problematic, depends on what format the header text is in

await t
    .expect(isTodayOrTomorrow(headerDate)).eql(true);

Those two functions could (perhaps should) go into a different file, so you keep your test file (and test case) clean with only those 4 last non-empty lines.


And when we're into testing here, you might want to check these two functions as well, it will become useful when you find a better solution later.

Using mocha and chain:

describe('isTodayOrTomorrow', function () {
      it('should return true for today', function () {
        expect(isTodayOrTomorrow(new Date())).to.equal(true);
    });
    
    it('should return true for tomorrow', function () {
        let date = new Date();
        date.setDate(date.getDate() + 1);
        expect(isTodayOrTomorrow(date)).to.equal(true);
    });
    
    it('should return false for yesterday', function () {
        let date = new Date();
        date.setDate(date.getDate() - 1);
        expect(isTodayOrTomorrow(date)).to.equal(false);
    });
    
    it('should return false for day after tomorrow', function () {
        let date = new Date();
        date.setDate(date.getDate() + 2);
        expect(isTodayOrTomorrow(date)).to.equal(false);
    });
});

describe('getTodayWithOffset', function () {
      it('should return object', function () {
        expect(typeof getTodayWithOffset()).to.equal('object');
    });   
    
    it('should return Date object', function () {
        expect(getTodayWithOffset() instanceof Date).to.equal(true);
    });
    
    it('should return today for no parameter', function () {
        const today = new Date();
        expect(getTodayWithOffset().toLocaleDateString()).to.equal(today.toLocaleDateString());
    });
    
    it('should return tomorrow for parameter equal 1', function () {
        const date = new Date();
        date.setDate(date.getDate() + 1);
        expect(getTodayWithOffset(1).toLocaleDateString()).to.equal(date.toLocaleDateString());
    });
    
    it('should return yesterday for parameter equal -1', function () {
        const date = new Date();
        date.setDate(date.getDate() - 1);
        expect(getTodayWithOffset(-1).toLocaleDateString()).to.equal(date.toLocaleDateString());
    });
});

Solution 2:[2]

A more minimalistic solution to achieve the desired behavior could be the following:

const datesToCheckFor = ["todaysDate", "tomorrowsDate"]
await t.expect(datesToCheckFor.some(date => Site.reportValues.reportHeaderInfo.innerText.includes(date))).ok("Expecting at least one of my dates to be in there!")

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Martin H.