codeceptjs / CodeceptJS

Supercharged End 2 End Testing Framework for NodeJS
http://codecept.io
MIT License
4.12k stars 727 forks source link

[FEATURE REQUEST] Add Custom Strategy Locators to Playwright #4107

Open tsuemura opened 10 months ago

tsuemura commented 10 months ago

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

kobenguyent commented 10 months ago

@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.

tsuemura commented 10 months ago

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

kobenguyent commented 10 months ago

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();
tsuemura commented 10 months ago

@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.

github-actions[bot] commented 7 months ago

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

DavertMik commented 7 months ago

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

kobenguyent commented 7 months ago

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

tsuemura commented 7 months ago

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

kobenguyent commented 7 months ago

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

github-actions[bot] commented 3 months ago

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