Cucumber: Can't convert DataTable to List<java.lang.String>. There was a table cell converter but the table was too wide to use it
Asked Answered
A

6

6

Feature file:

Scenario: Login to application
Given I open my application
And I login with following credentials 
| admin | pass1234 |

StepDefs:

@When("^I login with following credentials$")
public void i_login_with_following_credentials(DataTable dt) {
    List<String> list = dt.asList(String.class);
    System.out.println("Username - " + list.get(0));
    System.out.println("Password - " + list.get(1));
}

The error:

io.cucumber.datatable.UndefinedDataTableTypeException: Can't convert DataTable to List<java.lang.String>.
There was a table cell converter but the table was too wide to use it.
Please reduce the table width or register a TableEntryTransformer or TableRowTransformer for java.lang.String.

<cucumber.version>5.4.1</cucumber.version>
<junit.version>4.13</junit.version>

Could you please advice? What exactly should be added? Thank you.

Avellaneda answered 13/3, 2020 at 18:20 Comment(0)
C
9

You're trying to turn a data table into a list of strings. Because lists are vertical and because String can take up exactly one cell Cucumber expects that you have a table that has exactly one column.

| admin    |
| pass1234 | 

But you can also transpose the data table:

List<String> list = dt.transpose().asList(String.class)

Or simply access the cells directly:

String username = dt.cell(0,0);
String password = dt.cell(0,1);
Climacteric answered 14/3, 2020 at 11:18 Comment(1)
@m-p-korstanje it looks like dataTable.asList() does the job. Is there a way to register this behaviour as default for list of strings?Colson
G
3

Use asLists insted of asList to work

Gastritis answered 22/5, 2021 at 15:15 Comment(0)
H
1

Just use :

List<String> userAndPassword = db.row(0)
Hopehopeful answered 16/3, 2020 at 11:42 Comment(0)
S
1

As you were using asList() method which will return List of Strings. Instead of that you should use asLists() method which will return List of List of Strings. As shown in below code-

public void user_enters_following_user_details(DataTable dataTable) {
        List<List<String>> userDataList=dataTable.asLists(String.class);
        for(List<String> e:userDataList) {
            System.out.println(e);
        }
Sola answered 18/11, 2021 at 7:38 Comment(1)
Code without any explanation are rarely helpful. Stack Overflow is about learning, not providing snippets to blindly copy and paste. Please edit your question and explain how it answers the specific question being asked. See How to Answer.Placer
C
0

Using asList() method without class type argument does the job.

dt.asList(String.class) -> dt.asList()

    /**
     * Returns a list view on the table. Contains the cells ordered from
     * left to right, top to bottom starting at the top left.
     *
     * @return the cells of the table
     */
    public List<String> asList() {
        return new ListView();
    }

Test feature:

  Scenario: Testing DataTable asList method
    When I will pass list o strings
      | a | b |
    When I will pass list o strings
      | a |
      | b |
    When I will pass list o strings
      | a | b |
      | a | b |
    When I will pass list o strings
      | a | a |
      | b | b |

Step definition:

   @When("^I will pass list o strings$")
    public void i_will_pass_list_o_strings(DataTable arg1) throws Throwable {
        System.out.println(arg1);
        System.out.println(arg1.asList());
    }

This produces:

      | a | b |
[a, b]

      | a |
      | b |
[a, b]

      | a | b |
      | a | b |
[a, b, a, b]

      | a | a |
      | b | b |
[a, a, b, b]
Colson answered 3/12, 2020 at 15:42 Comment(0)
M
0

You are trying to convert a io.Cucumber.DataTable into a list of Strings, however your DataTable contains 2 columns. Using the asList() method only works on DataTables which have 1 column, hence the error message indicating that the table is too wide to convert.

You can convert your Datatable with 2 columns by using the asLists method:

List<List<String>> list = dt.asLists(String.class);

System.out.println("Username - " + list.get(0).get(0));
System.out.println("Password - " + list.get(0).get(1));

However this can get quite confusing to read. I would recommend using headings and converting the DataTable using the asMaps() method:

Scenario: Login to application
Given I open my application
And I login with following credentials 
| username | password |
| admin    | pass1234 |
List<Map<String, String>> rows = dt.asMaps(String.class, String.class);
System.out.println("Username - " + rows.get(0).get("username"));
System.out.println("Password - " + rows.get(0).get("password"));

A good introduction on how to work with Cucumber DataTables is this Baeldung article: https://www.baeldung.com/cucumber-data-tables

Mammary answered 4/5, 2022 at 12:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.