3

I am trying to write something to check that "About Us" exist on the following page: https://www.aggrowth.com/en-us/about-us and I am just hitting a wall. It shouldn't be difficult, but I have spent too much time on this.

We are using Gherking-testcafe: https://www.npmjs.com/package/gherkin-testcafe

NPM: 6.9.0

TestCafe: 1.0.1

Gherking-Testcafe: 2.0.0

I tried (All below was tested isolation, aka all of the different t.expect was run by themselves):

  const h1AboutUs = await Selector('h1');

  await t.expect(h1AboutUs.innerText).eql('About Us');
  await t.expect(h1AboutUs.innerText).contains('About Us');
  await t.expect(h1AboutUs.value).eql('About Us');
  await t.expect(Selector('html').textContent).contains('About Us');

and tried removing the await:

  const h1AboutUs = Selector('h1'); 

  await t.expect(h1AboutUs.innerText).eql('About Us');
  await t.expect(h1AboutUs.innerText).contains('About Us');
  await t.expect(h1AboutUs.value).eql('About Us');
  await t.expect(Selector('html').textContent).contains('About Us');

It works if I do:

This is the test I have:

When("I see the page load", async t => {
  const h1AboutUs = await Selector('h1');

  await t.expect(h1AboutUs.visible).eql(true);
  await t.hover(h1AboutUs);
  await t.expect(h1AboutUs.value).contains('about');
  console.log(h1AboutUs.value);
});

My testCafe runner:

const createTestCafe = require('gherkin-testcafe');
const fs = require('fs');
const reportPath = './frontend/src/tests/test-reports'
let testcafe = null;

function readTestCafeConfig() {
  configData = fs.readFileSync('.testcaferc.json', 'utf8');
  const js = JSON.parse(configData);
  return getJSONValues(js, 'src');
};

function getJSONValues(obj, key) {
  var objects = [];

  for (var i in obj) {
    if (!obj.hasOwnProperty(i)) continue;
    if (i === key) {
      objects.push(obj[i]);
    }
  }
  return objects;
}

createTestCafe('localhost', 1337, 1338)
  .then(tc => {
    testcafe = tc;
    const runner = testcafe.createRunner();
    const src = readTestCafeConfig();

    return runner
      .src([src])
      .browsers('chrome')
      .reporter(['spec', {
        name: 'json',
        output: `${reportPath}/report/report.json`
      },
        {
          name: 'xunit',
          output: `${reportPath}/report/report.xml`
        }])
      // .video(`${reportPath}/videos`, {
      //   singleFile: true,
      //   failedOnly: true,
      //   pathPattern: '${USERAGENT}/${FILE_INDEX}.mp4'
      // })
      .tags('@aboutUs')
      .run();
  })
  .then(failedCount => {
    console.log('Tests failed: ' + failedCount);
    testcafe.close();
  });

The error I get in the console is:

1) Selector cannot implicitly resolve the test run in context of which it should be executed. If you need to call Selector from the Node.js API callback, pass the test controller manually via
      Selector's `.with({ boundTestRun: t })` method first. Note that you cannot execute Selector outside the test code.

      Browser: Chrome 74.0.3729 / Mac OS X 10.14.4

         12 |});
         13 |
         14 |When("I see the page load", async t => {
         15 |  const h1AboutUs = await Selector('h1');
         16 |
       > 17 |  await t.expect(h1AboutUs.visible).eql(true);
         18 |  await t.hover(h1AboutUs);
         19 |  await t.expect(h1AboutUs.value).contains('about');
         20 |  console.log(h1AboutUs.value);
         21 |});
         22 |

I expect not to see this error msg

Alex Skorkin
  • 4,264
  • 3
  • 25
  • 47

1 Answers1

7

You need to implement Selector binding to TestCafe's test controller for such tests. Please have a look at the following example:

const { Given, Then, Before } = require('cucumber');
const { Selector: NativeSelector }  = require('testcafe');

const Selector = (input, t) => {
    return NativeSelector(input).with({ boundTestRun: t });
};

Before('@aboutHook', async () => {
    console.log('Running AGI test.');
});

Given("I am open AGI page", async t => {
    await t.navigateTo('https://www.aggrowth.com/en-us/about-us');
});

Then("I should see check about us", async t => {
    const h1AboutUs = Selector('h1', t); 
    //or const h1AboutUs = await Selector('h1', t); if you need

    await t
        .expect(h1AboutUs.visible).eql(true)
        .hover(h1AboutUs);
});

You can get more examples in the gherkin-testcafe repository. Note also that the h1 element doesn't have a property value. You can learn more about TestCafe Selectors and their properties in TestCafe Docs.

Helen Dikareva
  • 1,026
  • 6
  • 7
  • 1
    I have implemented my selector as a "require", since it is being used everywhere and I know that TestCafe might implement Gherkin as a standard, so I thought it would be easier to change one file then multiple files :) Thanks for you answer, will give it a try! :) – Dennis Thisner May 21 '19 at 14:53
  • This means that I am not able to check what text/"value" the "h1" contains? – Dennis Thisner May 21 '19 at 15:21
  • 4
    This means that you can check the text of the `h1` element using `h1AboutUs.textContent` or `h1AboutUs.innerText`. But elements like headings, paragraphs, div, etc. don't have a `value` property. See [the list](https://developer.mozilla.org/tr/docs/Web/HTML/Attributes) of elements that have the `value` property. – Helen Dikareva May 22 '19 at 06:40
  • Thank you for your quick and detail responses :) – Dennis Thisner May 22 '19 at 16:51