Commonly Used Functions

# test

test is a central function which is used to create a testcase unit. Full info ➤

test("It should print 'hello world'", () => {
    chunk(() => {
        console.log("hello world");
    });
});
➜ glace-core: ./bin/glace example.js

suite: Session 2018-11-15 09:27:15

  test: It should print 'hello world'
hello world
    ✓ chunk

  ✓ 1 passed test
  1 executed chunk

  Summary tests time is 0.003 sec

-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report

test should contain as minimum one chunk, named or unnamed.

# chunk

chunk is independently executed part of test. Independently means even if first chunk is failed, other chunks will be executed in any case. Full info ➤

test("It should include one unnamed chunk", () => {
    chunk(() => {
        console.log("do some stuff");
    });
});

test("It should include one named chunk", () => {
    chunk("first chunk", () => {
        console.log("do some stuff");
    });
});

test("It should include several chunks", () => {
    chunk("first chunk", () => {
        console.log("do some stuff");
    });
    chunk("second chunk", () => {
        console.log("do some stuff");
    });
});

test("It should include failed & passed chunks", () => {
    chunk("which is failed", () => {
        throw Error("BOOM!");
    });
    chunk("which is passed", () => {
        console.log("do some stuff");
    });
});
➜ glace-core: ./bin/glace example.js

suite: Session 2018-11-15 09:38:45

  test: It should include one unnamed chunk
do some stuff
    ✓ chunk

  test: It should include one named chunk
do some stuff
    ✓ chunk: first chunk

  test: It should include several chunks
do some stuff
    ✓ chunk: first chunk
do some stuff
    ✓ chunk: second chunk

  test: It should include failed & passed chunks
    ✖ chunk: which is failed
do some stuff
    ✓ chunk: which is passed

  ✓ 3 passed tests
  ✖ 1 failed test
  6 executed chunks

  Summary tests time is 0.005 sec

TEST FAILURES:

test: It should include failed & passed chunks

which is failed
message: BOOM!
stack: Error: BOOM!
    at chunk (example.js:24:15)
    at Context.<anonymous> (lib/globals/chunk.js:88:18)
    at next (lib/hacking.js:45:20)
    at Immediate.<anonymous> (lib/hacking.js:88:9)

-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report

# before

before is a hook executed before all chunks inside a test or before all tests inside a suite / scope / session. Full info ➤

test("It should execute hook before all chunks", () => {
    before(() => {
        console.log("some stuff before chunks");
    });
    chunk("first chunk", () => {
        console.log("do some stuff");
    });
    chunk("second chunk", () => {
        console.log("do some stuff");
    });
});

# after

after is a hook executed after all chunks inside a test or after all tests inside a suite / scope / session. Full info ➤

test("It should execute hook after all chunks", () => {
    chunk("first chunk", () => {
        console.log("do some stuff");
    });
    chunk("second chunk", () => {
        console.log("do some stuff");
    });
    after(() => {
        console.log("some stuff after chunks");
    });
});

# beforeChunk

beforeChunk is a hook executed before each chunk inside a test. Full info ➤

test("It should execute hook before each chunk", () => {
    beforeChunk(() => {
        console.log("some stuff before each chunk");
    });
    chunk("first chunk", () => {
        console.log("do some stuff");
    });
    chunk("second chunk", () => {
        console.log("do some stuff");
    });
});

# afterChunk

afterChunk is a hook executed after each chunk inside a test. Full info ➤

test("It should execute hook after each chunk", () => {
    chunk("first chunk", () => {
        console.log("do some stuff");
    });
    chunk("second chunk", () => {
        console.log("do some stuff");
    });
    afterChunk(() => {
        console.log("some stuff after each chunk");
    });
});

# $

$ is the steps namespace, central concept of glace philosophy. Ideally and normally in glace tests to have only step calls inside test chunks. glace-core provides only basic steps, other steps for specific actions are provided by plugins or should be implemented together with tests development. There are more examples of steps usage in glace-js. And here some basic:

suite("Timer steps", () => {

    test("It should sleep 1 sec", () => {
        chunk(async () => {
            await $.pause(1, "sleep 1 sec");
        });
    });

    test("It should pass timer check", () => {
        chunk(async () => {
            await $.startTimer();
            await $.pause(1, "sleep");
            await $.checkTimer({ "to be above": 1 });
        });
    });

    test("It should fail timer check", () => {
        chunk(async () => {
            await $.startTimer();
            await $.pause(1, "sleep");
            await $.checkTimer({ "to be below": 1 });
        });
    });

    test("It should fail because timer is not started", () => {
        chunk(async () => {
            await $.startTimer();
            await $.pause(1, "sleep");
            await $.stopTimer();
            await $.checkTimer({ "to be equal": 1 });
        });
    });
});
➜ glace-core: ./bin/glace example.js

suite: Session 2018-11-16 08:29:39

  suite: Timer steps

    test: It should sleep 1 sec
      ✓ chunk

    test: It should pass timer check
      ✓ chunk

    test: It should fail timer check
      ✖ chunk

    test: It should fail because timer is not started
      ✖ chunk

  ✓ 2 passed tests
  ✖ 2 failed tests
  4 executed chunks

  Summary tests time is 4.032 sec

TEST FAILURES:

test: It should fail timer check

message: Timing is failed: expected 1.005 to be below 1
stack: AssertionError: Timing is failed: expected 1.005 to be below 1
    at Proxy.Assertion.correspond (lib/matcher.js:50:27)
    at Proxy.checkTimer (lib/steps/timer.js:135:56)
    at chunk (example.js:23:21)
    at <anonymous>

test: It should fail because timer isn't started

message: Timer isn't started: expected null to exist
stack: AssertionError: Timer isn't started: expected null to exist
    at Proxy.getTimer (lib/steps/timer.js:103:54)
    at Proxy.checkTimer (lib/steps/timer.js:135:21)
    at chunk (example.js:32:21)
    at <anonymous>

-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report

# CONF

CONF refers to glace configuration and is mostly used inside steps, features or iterators, rather than inside tests directly. For example, glace-core/lib/globals/forEachLanguage.js#L66:

scope(`${name} "${lang}"`, () => {
    let oldLang;

    before(() => {
        if (CONF.test.curCase) {
            oldLang = CONF.test.curCase.testParams.language;
            CONF.test.curCase.testParams.language = lang;
        }
    });

    U.wrap(fixtures, () => func(lang))();

    after(() => {
        if (CONF.test.curCase) {
            CONF.test.curCase.testParams.language = oldLang;
        }
    });
});

CONF is global object for all glace components, which means that even if some glace plugin imports own config module internally, finally it works in the same global config namespace. Full info ➤

# fixtures

Fixtures are reusable functions, which can add hooks before and after test or group of tests. They were introduced to glace-core under impression of pytest fixtures. Simple fixture can be presented as:

const myFixture = testFunc => {
    before(() => console.log("fixture before"));
    testFunc();
    after(() => console.log("fixture after"));
};

Now it can be reusable as many times as it needs. For example:

suite("My suite", [myFixture], () => {

    test("first test", () => {
        chunk(() => {});
    });

    test("second test", [myFixture], () => {
        chunk(() => {});
    });
});

Run result:

➜ glace-core: ./bin/glace example.js

suite: Session 2018-11-22 07:39:21

  suite: My suite
fixture before

    test: first test
      ✓ chunk

    test: second test
fixture before
      ✓ chunk
fixture after
fixture after

  ✓ 2 passed tests
  2 executed chunks

  Summary tests time is 0.005 sec

-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report

Fixtures can be used with test, scope, suite, session and forEachLanguage.

Many glace plugins offer fixtures as wrappers on their steps. For example, glace-web/lib/fixtures.js#L18. And glace-js session is fully based on fixtures reusage.

# iterators

iterators are used to make parametrization over tests or chunks. Underhood iterators are cycles. glace-core provides iterator forEachLanguage to make easy localisation tests.

suite("Localisation tests", () => {
    test("my test", () => {
        forEachLanguage(lang => {
            chunk(() => {
                // someLangSpecificStuff(lang);
            });
        });
    });
});
➜ glace-core: ./bin/glace example.js --languages en,ru,fr

suite: Session 2018-11-22 07:39:21

  suite: Localisation tests

    test: my test

      scope: for language "en"
        ✓ chunk

      scope: for language "ru"
        ✓ chunk

      scope: for language "fr"
        ✓ chunk

  ✓ 1 passed test
  3 executed chunks

  Summary tests time is 0.004 sec

-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report

# suite

suite is used to group tests. Full info ➤

suite("my tests", () => {
    test("first test", () => {
        chunk(() => {});
    });

    test("second test", () => {
        chunk(() => {});
    });
});
➜ glace-core: ./bin/glace example.js

suite: Session 2018-11-22 07:39:21

  suite: my tests

    test: first test
      ✓ chunk

    test: second test
      ✓ chunk

  ✓ 2 passed tests
  2 executed chunks

  Summary tests time is 0.004 sec

-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report

# scope

scope is used to group tests or chunks. Full info ➤

test("my test", () => {

    scope("user chunks", () => {
        chunk("login as user", () => {});
        chunk("post a message", () => {});
    });

    scope("admin chunks", () => {
        chunk("login as admin", () => {});
        chunk("moderate messages", () => {});
    });
});
➜ glace-core: ./bin/glace example.js

suite: Session 2018-11-22 07:39:21

  test: my test

    scope: user chunks
      ✓ chunk: login as user
      ✓ chunk: post a message

    scope: admin chunks
      ✓ chunk: login as admin
      ✓ chunk: moderate messages

  ✓ 1 passed test
  4 executed chunks

  Summary tests time is 0.004 sec

-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report

# session

session is root suite, which is created automatically (not need to use it explicitly). Full info ➤

But it can be overridden to extend its functionality, for example glace-js/lib/globals.js#L13:

const gSession = session;
global.session = (name, fixtures, func) => {
    if (_.isFunction(fixtures)) [func, fixtures] = [fixtures];
    if (_.isArray(name)) [fixtures, name] = [name];
    if (_.isFunction(name)) [func, name] = [name];
    fixtures = fixtures || [];
    if (CONF.web.use && !CONF.cluster.slavesNum) fixtures.push(fxKillWebdriver);
    if (CONF.xvfb.use) fixtures.push(fxXvfb);
    if (CONF.proxy.global) fixtures.push(fxGlobalProxy);
    if (CONF.proxy.http) fixtures.push(fxHttpProxy);
    if (CONF.web.use && !CONF.webdriver.host) fixtures.push(fxSelenium);
    if (CONF.web.use) fixtures.push(fxBrowser);
    if (CONF.image.screenOnFail) fixtures.push(fxScreenOnFail);
    gSession(name, fixtures, func);
};