Skip to content

Commit

Permalink
fix: 🐛 Manage the log
Browse files Browse the repository at this point in the history
The official documentation suggests to customize the use of Cypress.log
https://docs.cypress.io/api/cypress-api/cypress-log.html#Syntax

Closes: #53
  • Loading branch information
NoriSte committed Oct 30, 2019
1 parent 2cfdb27 commit d97e3fb
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 137 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,13 @@ A function that must return a truthy value when the wait is over.

Pass in an options object to change the default behavior of `cy.waitUntil()`.

Option | Default | Description
--- | --- | ---
`errorMsg` | `Timed out retrying` | The error message to write.
`timeout` | `5000` | Time to wait for the `checkFunction` to return a truthy value before throwing an error.
`interval` | `200` | Time to wait between the `checkFunction` invocations.
| Option | Default | Description |
| ------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `errorMsg` | `Timed out retrying` | The error message to write. |
| `timeout` | `5000` | Time to wait for the `checkFunction` to return a truthy value before throwing an error. |
| `interval` | `200` | Time to wait between the `checkFunction` invocations. |
| `description` | `waitUntil` | The name logged into the Cypress Test Runner. |
| `logger` | `Cypress.log` | A custom logger in place of the default [Cypress.log](https://docs.cypress.io/api/cypress-api/cypress-log.html). It's useful just for debugging purposes. |

<br />
<br />
Expand Down
255 changes: 162 additions & 93 deletions cypress/integration/plugin.spec.js
Original file line number Diff line number Diff line change
@@ -1,167 +1,236 @@
/// <reference types="Cypress" />

context('Actions', () => {
context("Cypress Wait Until", () => {
beforeEach(() => {
cy.visit('http://localhost:5000/')
})
cy.visit("http://localhost:5000/");
});

it('Should work with an immediately-satisfied condition', () => {
const COOKIE_NAME = 'immediate-cookie'
const EXPECTED_COOKIE_VALUE = 'Set'
cy.get('#' + COOKIE_NAME).click()
it("Should work with an immediately-satisfied condition", () => {
const COOKIE_NAME = "immediate-cookie";
const EXPECTED_COOKIE_VALUE = "Set";
cy.get("#" + COOKIE_NAME).click();

const checkFunction = () => cy.getCookie(COOKIE_NAME)
.then(cookieValue => cookieValue && cookieValue.value === EXPECTED_COOKIE_VALUE)
const checkFunction = () =>
cy
.getCookie(COOKIE_NAME)
.then(cookieValue => cookieValue && cookieValue.value === EXPECTED_COOKIE_VALUE);

cy.waitUntil(checkFunction)
cy.waitUntil(checkFunction);

cy.getCookie(COOKIE_NAME).then(cookieValue => expect(cookieValue.value).to.be.equal(EXPECTED_COOKIE_VALUE));
})
cy.getCookie(COOKIE_NAME).then(cookieValue =>
expect(cookieValue.value).to.be.equal(EXPECTED_COOKIE_VALUE)
);
});

it('Should work with a condition satisfied after a random delay', () => {
const COOKIE_NAME = 'after-a-while-cookie'
const EXPECTED_COOKIE_VALUE = 'Set'
cy.get('#' + COOKIE_NAME).click()
it("Should work with a condition satisfied after a random delay", () => {
const COOKIE_NAME = "after-a-while-cookie";
const EXPECTED_COOKIE_VALUE = "Set";
cy.get("#" + COOKIE_NAME).click();

const checkFunction = () => cy.getCookie(COOKIE_NAME)
.then(cookieValue => cookieValue && cookieValue.value === EXPECTED_COOKIE_VALUE)
const checkFunction = () =>
cy
.getCookie(COOKIE_NAME)
.then(cookieValue => cookieValue && cookieValue.value === EXPECTED_COOKIE_VALUE);

cy.waitUntil(checkFunction)
cy.waitUntil(checkFunction);

cy.getCookie(COOKIE_NAME).then(cookieValue => expect(cookieValue.value).to.be.equal(EXPECTED_COOKIE_VALUE));
})
cy.getCookie(COOKIE_NAME).then(cookieValue =>
expect(cookieValue.value).to.be.equal(EXPECTED_COOKIE_VALUE)
);
});

it('Should apply options correctly', () => {
const COOKIE_NAME = 'after-a-while-cookie'
const EXPECTED_COOKIE_VALUE = 'Set'
it("Should apply options correctly", () => {
const COOKIE_NAME = "after-a-while-cookie";
const EXPECTED_COOKIE_VALUE = "Set";

cy.once('fail', err => {
expect(err.message).to.be.equal('Timed out retrying')
})
cy.once("fail", err => {
expect(err.message).to.be.equal("Timed out retrying");
});

cy.get('#' + COOKIE_NAME).click()
cy.get("#" + COOKIE_NAME).click();

const checkFunction = () => cy.getCookie(COOKIE_NAME)
.then(cookieValue => cookieValue && cookieValue.value === EXPECTED_COOKIE_VALUE)
const checkFunction = () =>
cy
.getCookie(COOKIE_NAME)
.then(cookieValue => cookieValue && cookieValue.value === EXPECTED_COOKIE_VALUE);

cy.waitUntil(checkFunction, {
interval: 100,
timeout: 900
})
})
});
});

it('Should check value equality check', () => {
const COOKIE_NAME = 'change-after-a-while-cookie'
const EXPECTED_COOKIE_VALUE = '7'
cy.get('#' + COOKIE_NAME).click()
it("Should log a custom logging description", () => {
const COOKIE_NAME = "after-a-while-cookie";
const EXPECTED_COOKIE_VALUE = "Set";

const checkFunction = () => cy.getCookie(COOKIE_NAME)
.then(cookieValue => cookieValue && cookieValue.value === EXPECTED_COOKIE_VALUE)
cy.once("fail", err => {
expect(err.message).to.be.equal("Timed out retrying");
});

cy.waitUntil(checkFunction)
cy.get("#" + COOKIE_NAME).click();

cy.getCookie(COOKIE_NAME).then(cookieValue => expect(cookieValue.value).to.be.equal(EXPECTED_COOKIE_VALUE));
})
const checkFunction = () =>
cy
.getCookie(COOKIE_NAME)
.then(cookieValue => cookieValue && cookieValue.value === EXPECTED_COOKIE_VALUE);

it('Should make the test fail with an unsatisfied condition', () => {
const COOKIE_NAME = 'unknwon-cookie'
const EXPECTED_COOKIE_VALUE = 'Set'
cy.waitUntil(checkFunction, {
interval: 100,
timeout: 900
});
});

it("Should check value equality check", () => {
const COOKIE_NAME = "change-after-a-while-cookie";
const EXPECTED_COOKIE_VALUE = "7";
cy.get("#" + COOKIE_NAME).click();

const checkFunction = () =>
cy
.getCookie(COOKIE_NAME)
.then(cookieValue => cookieValue && cookieValue.value === EXPECTED_COOKIE_VALUE);

cy.waitUntil(checkFunction);

cy.getCookie(COOKIE_NAME).then(cookieValue =>
expect(cookieValue.value).to.be.equal(EXPECTED_COOKIE_VALUE)
);
});

it("Should make the test fail with an unsatisfied condition", () => {
const COOKIE_NAME = "unknwon-cookie";
const EXPECTED_COOKIE_VALUE = "Set";

cy.once('fail', err => {
expect(err.message).to.be.equal('Timed out retrying')
})
cy.once("fail", err => {
expect(err.message).to.be.equal("Timed out retrying");
});

const checkFunction = () => cy.getCookie(COOKIE_NAME)
.then(cookieValue => cookieValue && cookieValue.value === EXPECTED_COOKIE_VALUE)
const checkFunction = () =>
cy
.getCookie(COOKIE_NAME)
.then(cookieValue => cookieValue && cookieValue.value === EXPECTED_COOKIE_VALUE);

cy.waitUntil(checkFunction)
})
cy.waitUntil(checkFunction);
});

it('Should work sync', () => {
const checkFunction = () => true
it("Should work sync", () => {
const checkFunction = () => true;

cy.waitUntil(checkFunction)
})
cy.waitUntil(checkFunction);
});

it('Should work sync with retries', () => {
it("Should work sync with retries", () => {
let n = 4;
const checkFunction = () => {
n--;
return n < 0;
}
};

cy.waitUntil(checkFunction)
})
cy.waitUntil(checkFunction);
});

it('`checkFunction` should be a function', () => {
const ERROR_MESSAGE = '`checkFunction` parameter should be a function. Found: true'
it("`checkFunction` should be a function", () => {
const ERROR_MESSAGE = "`checkFunction` parameter should be a function. Found: true";

cy.once('fail', err => expect(err.message).to.be.equal(ERROR_MESSAGE))
cy.waitUntil(true)
})
cy.once("fail", err => expect(err.message).to.be.equal(ERROR_MESSAGE));
cy.waitUntil(true);
});

it('Should accept a custom error message', () => {
const COOKIE_NAME = 'unknwon-cookie'
const EXPECTED_COOKIE_VALUE = 'Set'
it("Should accept a custom error message", () => {
const COOKIE_NAME = "unknwon-cookie";
const EXPECTED_COOKIE_VALUE = "Set";

cy.once('fail', err => {
expect(err.message).to.be.equal('Custom error message')
})
cy.once("fail", err => {
expect(err.message).to.be.equal("Custom error message");
});

const checkFunction = () => cy.getCookie(COOKIE_NAME)
.then(cookieValue => cookieValue && cookieValue.value === EXPECTED_COOKIE_VALUE)
const checkFunction = () =>
cy
.getCookie(COOKIE_NAME)
.then(cookieValue => cookieValue && cookieValue.value === EXPECTED_COOKIE_VALUE);

cy.waitUntil(checkFunction, {errorMsg: 'Custom error message'})
})
cy.waitUntil(checkFunction, { errorMsg: "Custom error message" });
});

it('Should pass the result to the next command', () => {
it("Should pass the result to the next command", () => {
const result = 10;

const checkFunction = () => result;
const asyncCheckFunction = () => Promise.resolve(result);
const chainableCheckFunction = () => cy.wrap(result).then(wrappedResult => wrappedResult);

cy.waitUntil(checkFunction).should('eq', result)
cy.waitUntil(asyncCheckFunction).should('eq', result)
cy.waitUntil(chainableCheckFunction).should('eq', result)
})
cy.waitUntil(checkFunction).should("eq", result);
cy.waitUntil(asyncCheckFunction).should("eq", result);
cy.waitUntil(chainableCheckFunction).should("eq", result);
});

it('Should wait between every check', () => {
it("Should wait between every check", () => {
const interval = 100;
let previousTimestamp;

const checkFunction = () => {
const previousTimestampBackup = previousTimestamp;
const newTimestamp = Date.now();
previousTimestamp = newTimestamp;
if(previousTimestampBackup) {
if (previousTimestampBackup) {
const diff = newTimestamp - previousTimestampBackup;
return diff >= interval;
}
return false
}
return false;
};

const asyncCheckFunction = () => Promise.resolve(checkFunction());
const chainableCheckFunction = () => cy.wrap().then(() => checkFunction());

cy.log("Sync function");
cy.waitUntil(checkFunction, {interval})
cy.waitUntil(checkFunction, { interval });
cy.log("Async function");
cy.waitUntil(asyncCheckFunction, {interval})
cy.waitUntil(asyncCheckFunction, { interval });
cy.log("Chainable function");
cy.waitUntil(chainableCheckFunction, {interval})
})
cy.waitUntil(chainableCheckFunction, { interval });
});

it('Should be chainable', () => {
it("Should be chainable", () => {
const result = 10;
const checkFunction = () => result;
const checkFunctionWithSubject = subject => subject;

cy.waitUntil(checkFunction)
.should('eq', result)
cy.waitUntil(checkFunction).should("eq", result);

cy.wrap(result)
.waitUntil(checkFunctionWithSubject)
.should('eq', result)
})
})
.should("eq", result);
});

it("Should leverage Cypress.log", () => {
const checkFunction = () => true;

const logger = {
log: (...params) => Cypress.log(...params)
};
const spy = cy.spy(logger, "log");

cy.waitUntil(checkFunction, { logger: logger.log }).then(() => {
expect(spy).to.have.been.called;
const lastCallArgs = spy.lastCall.args[0];
expect(lastCallArgs).deep.include({ name: "waitUntil" });
});
});

it("Should accept a custom log description", () => {
const checkFunction = () => true;
const description = "custom description";

const logger = {
log: (...params) => Cypress.log(...params)
};
const spy = cy.spy(logger, "log");

cy.waitUntil(checkFunction, { logger: logger.log, description }).then(() => {
expect(spy).to.have.been.called;
const lastCallArgs = spy.lastCall.args[0];
expect(lastCallArgs).deep.include({ name: description });
});
});
});
40 changes: 24 additions & 16 deletions cypress/types/plugin.spec.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
/// <reference types="Cypress" />

cy.waitUntil(() => true)
cy.waitUntil(() => false)
cy.waitUntil(() => Promise.resolve(true))
cy.waitUntil(() => Promise.resolve(false))
cy.waitUntil(() => true);
cy.waitUntil(() => false);
cy.waitUntil(() => Promise.resolve(true));
cy.waitUntil(() => Promise.resolve(false));

cy.waitUntil(() => true, {})
cy.waitUntil(() => false, {})
cy.waitUntil(() => Promise.resolve(true), {})
cy.waitUntil(() => Promise.resolve(false), {})
cy.waitUntil(() => true, {});
cy.waitUntil(() => false, {});
cy.waitUntil(() => Promise.resolve(true), {});
cy.waitUntil(() => Promise.resolve(false), {});

cy.waitUntil(() => true, { timeout: 500 })
cy.waitUntil(() => false, { timeout: 500 })
cy.waitUntil(() => Promise.resolve(true), { timeout: 500 })
cy.waitUntil(() => Promise.resolve(false), { timeout: 500 })
cy.waitUntil(() => true, { timeout: 500 });
cy.waitUntil(() => false, { timeout: 500 });
cy.waitUntil(() => Promise.resolve(true), { timeout: 500 });
cy.waitUntil(() => Promise.resolve(false), { timeout: 500 });

cy.waitUntil(() => true, { errorMsg: "Custom error message" })
cy.waitUntil(() => false, { errorMsg: "Custom error message" })
cy.waitUntil(() => Promise.resolve(true), { errorMsg: "Custom error message" })
cy.waitUntil(() => Promise.resolve(false), { errorMsg: "Custom error message" })
cy.waitUntil(() => true, { errorMsg: "Custom error message" });
cy.waitUntil(() => false, { errorMsg: "Custom error message" });
cy.waitUntil(() => Promise.resolve(true), { errorMsg: "Custom error message" });
cy.waitUntil(() => Promise.resolve(false), { errorMsg: "Custom error message" });

cy.waitUntil(() => true, { description: "Custom description" });

cy.waitUntil(() => true, {
logger: ({ name, message, consoleProps }) => {
console.log({ name, message, consoleProps });
}
});
Loading

0 comments on commit d97e3fb

Please sign in to comment.