CodeceptJS icon indicating copy to clipboard operation
CodeceptJS copied to clipboard

[FEATURE REQUEST] Add Custom Strategy Locators to Playwright

Open tsuemura opened this issue 2 years ago • 10 comments

What are you trying to achieve?

https://codecept.io/locators/#custom-strategy-locators

This Custom Strategy Locators feature is currently only available on WebdriverIO. However, since it's just a JavaScript execution to return element(s), it should be technically possible to export to Playwright (and the other web automation helpers). If we can do so, it makes easier to find elements more flexibly.

Example: Look up a table cell by the header row and column

// in codecept.conf.js

const findTableCellByHeader = (selector, rowHeader, colHeader) => {

  // Find the table
  const table = root.querySelector(selector)
  if (!table) {
    throw new Error(`Table not found: ${selector}`);
  }

  // Find the row
  const row = Array.from(table.querySelectorAll('tr')).find(
    (tr) => tr.querySelector('th')?.textContent === rowHeader
  );
  if (!row) {
    throw new Error(`Row not found: ${rowHeader}`);
  }

  // Find the column index
  const colIndex = Array.from(table.querySelectorAll('tr')[0].cells).findIndex(
    (cell) => cell.textContent === colHeader
  );
  if (colIndex === -1) {
    console.log('Column not found');
    return null;
  }

  // Return the cell at the intersection of the row and column
  return row.cells[colIndex];
}

// under WebDriver Helpers Configuration
WebDriver: {
  ...
  customLocatorStrategies: {
    findTableCellByHeader
  }
}

This is the example of Webdriver helper, and I would like to enable it to the Playwright helper.

What do you get instead?

Currently the CustomLocator plugin only allows to use CSS or XPath, does not allow to find elements by JavaScript.

Details

N/A

tsuemura avatar Jan 05 '24 02:01 tsuemura

@tsuemura may you share some showcases of this feature? Cause I remembered we have getWebElements and using customLocator plugin. Or maybe I haven't got what you're aiming for.

kobenguyent avatar Jan 05 '24 17:01 kobenguyent

@kobenguyent Good point. I added an example on the description. Does it makes sense to you?

tsuemura avatar Jan 06 '24 03:01 tsuemura

Thank you @tsuemura I just went through the codeceptjs and noticed this.

Does it help you to locate the desired element after you had the returned web elements?

Now we expose the WebElements that are returned by the WebHelper and you could make the subsequence actions on them.

// Playwright helper would return the Locator

I.amOnPage('/form/focus_blur_elements');
const webElements = await I.grabWebElements('#button');
webElements[0].click();

kobenguyent avatar Jan 07 '24 12:01 kobenguyent

@kobenguyent That's an option. However, I personally don't love to use webElements[0].click() because webElement does not click itself - I want to keep the excellent syntax of "I do something" as the same as the other CodeceptJS methods. But if I understand correctly, methods like I.click() do not take web elements as the argument.

tsuemura avatar Jan 07 '24 13:01 tsuemura

This issue is stale because it has been open for 90 days with no activity.

github-actions[bot] avatar Apr 07 '24 02:04 github-actions[bot]

@kobenguyent can we close this with support of pw locators in latest release? or it is something different?

DavertMik avatar Apr 12 '24 22:04 DavertMik

I guess the request from @tsuemura is something like supporting the finding elements by JavaScript, if I got it correctly.

kobenguyent avatar Apr 13 '24 04:04 kobenguyent

@kobenguyent Right. The request is not the same as supporting pw locators.

tsuemura avatar Apr 14 '24 12:04 tsuemura

@tsuemura if you already have the implementation for it, just don't hesitate to submit your PR.

kobenguyent avatar Apr 15 '24 11:04 kobenguyent