Convert HTML Table to the JavaScript Array

Hello everyone,

I’m here again! :slight_smile:

I’m trying to convert an HTML table to the JS Array, to compare values properly (cell by cell).

I’ve written the code below:

extractTableFrom: function(tableLocate){
document.querySelectorAll(${tableLocate} tr), function (tr) {
return‘td’), function (td) {
return td.innerHTML;

but the CodeceptJS doesn’t recognize the “document.” argument. I know that I could use this functions inside of “executeScript”, but how could I catch the value from it?

Do you know how can I unfold this problem? Any suggestion?

Thank you in advance


document is not available as CodeceptJS runs in Node.js context by default, and there is no document defined. In a browser context we can access document by default, this is document is available within executeScript, which runs a script in browser context.

You can grab the page source and operate on the result:

const pageSource = await I.grabSource();

Does it help?


Actually, I’ve already gotten by on our own in another way but seeing another approach is always good.

Thank you!

@andreyagra would you mind to share your solution with the community? Thanks!

1 Like

Sure, @paulb!

And sorry for my delay!
Just to clarify, my first intention was became this process more flexible (it was the reason of this post), but I need to deliver faster (I intend to improve as soon as I’m stepping up with tests coverage).
So, at this moment, my approach was just test the fields:

In my Step Class (called by newOrderSteps,js), I created two Hash Tables predicting the element positions, so, I created a method to browse in these elements, and in the Tests (in fact), I called this browse method, sending an array of hash table to check each value… :slight_smile: Easy to understand, right??? :laughing: Let me breakdown these points…

First of all:
In my Step Class (called by newOrderSteps,js):

  1. I created two Hash Tables with the elements position:

      itemsDetail: {qty: "td[1]",
                     item: "td[2]",
                     address: "td[5]",
                     nett: "td[7]",
                     purchaseDetail: "td[2]"
       fieldsResult: {
         orderResultTableMaster: locate('#tab1').find('table'),
         orderTypeResult: "//tbody/tr[1]/td[2]",
         orderAccount: "//tbody/tr[2]/td[1]",
         paymentBy: "//tbody/tr[2]/td[2]",
         billTo: "//tbody/tr[3]/td[1]",
         orderResultTableItems: locate('table.table-bordered.table-hover.table-order-items')
  2. So, I created a browse method:

     checkOrderItems (I, expectedValues){
         let baseHTMLCheck = "//tbody/tr[";
         for (const [index, item] of expectedValues.entries()){
           let indexOnHTMLTable = index + 1;
           let baseLocate = function (embeddedWord, position){
             position = position || indexOnHTMLTable;
             return baseHTMLCheck + position + `]/${embeddedWord}`;
           I.see(item.qty, locate(baseLocate(this.itemsDetail.qty)).inside(this.fieldsResult.orderResultTableItems));
           I.see(item.item, locate(baseLocate(this.itemsDetail.item)).inside(this.fieldsResult.orderResultTableItems));
           I.see(item.address, locate(baseLocate(this.itemsDetail.address)).inside(this.fieldsResult.orderResultTableItems));
           I.see(item.nett, locate(baseLocate(this.itemsDetail.nett)).inside(this.fieldsResult.orderResultTableItems));
           I.see(item.purchaseDetail, locate(baseLocate(this.itemsDetail.purchaseDetail, (indexOnHTMLTable * 2))).inside(this.fieldsResult.orderResultTableItems));

And finally, Inside of my test (in fact), I just called the browse method from Step Class:

 <Test Method>{ ...
        newOrderSteps.checkOrderItems(I, [{qty: 1, item: "Item purchased", address: "Address bla bla bla", nett: 1000.00, purchaseDetail: "Blue Circle with red arrows Item purchased"}]);

Is it clear??? :slightly_frowning_face:

By the way, I’m open to any suggestions…

1 Like