gpt4 book ai didi

javascript - 如何从 WebdriverIO 中的 WebElement 继承

转载 作者:行者123 更新时间:2023-12-04 02:25:41 27 4
gpt4 key购买 nike

我正在寻找一种从 WebElement 继承的方法对象 webdriverio返回,没有猴子补丁和 TS 类型支持(自动完成是必须的)。有没有办法做这样的事情?

class Checkbox extends WebdriverIOWebElement {
constructor() {
super($('div'))
}
// overriding base method
isDisplayed(): boolean {
// blabla some new logic here
}

check() {
if(!this.isChecked()) {
this.click()
}
}

uncheck() {
if(this.isChecked()) {
this.click()
}
}
}

最佳答案

举个例子,当我们在 HTML 中有一个新标签 (my-app) 并且我们必须使用 webdriverIO 构建一个登录案例时,

假设这是 HTML:

我们要做的是使用组件对象模式,组件对象模式试图减少重复并将组件的 api 移动到它自己的对象中。我们知道,为了与元素的 shadow DOM 交互,我们首先需要宿主元素。为您的组件对象使用基类使这非常简单。

这是一个简单的组件基类,它在其构造函数中获取宿主元素并将该元素的查询展开到浏览器对象,因此它可以在许多页面对象(或其他组件对象)中重用,而无需了解任何关于页面本身。

    class Component {

constructor(host) {
const selectors = [];
// Crawl back to the browser object, and cache all selectors
while (host.elementId && host.parent) {
selectors.push(host.selector);
host = host.parent;
}
selectors.reverse();
this.selectors_ = selectors;
}

get host() {
// Beginning with the browser object, reselect each element
return this.selectors_.reduce((element, selector) => element.$(selector), browser);
}
}

module.exports = Component;

那么我们要做的是,我们将为我们的 app-login 组件编写一个子类:
const Component = require('./component');

class Login extends Component {

get usernameInput() {
return this.host.shadow$('input #username');
}

get passwordInput() {
return this.host.shadow$('input[type=password]');
}

get submitButton() {
return this.login.shadow$('button[type=submit]');
}

login(username, password) {
this.usernameInput.setValue(username);
this.passwordInput.setValue(password);
this.submitButton.click();
}
}

module.exports = Login;

最后,我们可以在登录页面对象中使用组件对象:
const Login = require('./components/login');

class LoginPage {

open() {
browser.url('/login');
}

get app() {
return browser.$('my-app');
}

get loginComponent() {
// return a new instance of our login component object
return new Login(this.app.$('app-login'));
}

}

现在,此组件对象现在可以用于测试您的应用程序的任何页面或使用应用程序登录 Web 组件的部分,而无需了解该组件的结构。如果您稍后决定更改 Web 组件的内部结构,则只需更新组件对象即可。

现在我们通过使用 Shadow Dom Support 对 Check Box 组件应用相同的方法:
public class CheckBox extends Component {
public CheckBox(element) {
this.element = element;
}
get checkBoxSelector() {
return this.host.shadow$(element);
}
get void toggle() {
checkBoxSelector().click();
}
get void check() {
if (!isChecked()) {
toggle();
}
}
get void uncheck() {
if (isChecked()) {
toggle();
}
}
get boolean isChecked() {
return checkBoxSelector().isSelected();
}
}

然后我们可以编写一个 Check Box Controller 组件,它可以使用 id 获取复选框的实例并验证每一个都是必要的。
const CheckBox= require('./components/CheckBox');
class CheckBoxController{
open() {
browser.url('/login');
}
get checkboxComponent() {

// Using this we can verify whether the Specific Check Box has been Selected or Not
let element = browser.$('[id="lpagecheckbox"]');
return new CheckBox(element);
}
}

笔记 :

请承担这不是实际的代码,这只是模板的一部分,可以帮助我们朝着解决问题的方向前进。

来源竞争:

https://webdriver.io/docs/api/element/isSelected.html

https://webdriver.io/blog/2019/02/22/shadow-dom-support.html

https://webdriver.io/blog/2019/04/03/react-selectors.html

https://webdriver.io/docs/pageobjects.html

此外,如果我们使用 Selenium Webdriver ,这可以帮助我们实现它

这里我们有一个接口(interface),它实际上结合了所有 webdriver接口(interface),然后我们通过继承 Element 创建一个具体的实现类,最后让我们假设您需要的任何组件我们应该继承并使用它自己的实现,在这种情况下,让我们假设应该从元素实现类继承的复选框,最后通过实例化使用它的 Cranky 方式目的。 CheckBox cb = new CheckBox(element);cb.uncheck();
第1步:

创建一个结合所有 WebDriver 接口(interface)的接口(interface):
public interface Element extends WebElement, WrapsElement, Locatable {}

第2步:

元素实现继承元素类:
public class ElementImpl implements Element {

private final WebElement element;

public ElementImpl(final WebElement element) {
this.element = element;
}

@Override
public void click() {
element.click();
}

@Override
public void sendKeys(CharSequence... keysToSend) {
element.sendKeys(keysToSend);
}

// And so on, delegates all the way down...

}

第 3 步:
考虑您使用的任何组件,让我们假设在这种情况下为复选框
public class CheckBox extends ElementImpl {

public CheckBox(WebElement element) {
super(element);
}

public void toggle() {
getWrappedElement().click();
}

public void check() {
if (!isChecked()) {
toggle();
}
}

public void uncheck() {
if (isChecked()) {
toggle();
}
}

public boolean isChecked() {
return getWrappedElement().isSelected();
}
}

使用方法:
CheckBox cb = new CheckBox(element);
cb.uncheck();

如果你想要更清晰的方式来实现这样的东西:引用第三个链接
public class Part2ExampleTest {
private final WebDriver driver;

@FindBy(id = "checkbox")
CheckBox checkBox;

protected Part2ExampleTest(WebDriver driver) {
this.driver = driver;
}

protected static Part2ExampleTest initialize(WebDriver driver) {
return ElementFactory.initElements(driver, Part2ExampleTest.class);
}

@Test
public void simple() {
WebDriver driver = new FirefoxDriver();
Part2ExampleTest page = initialize(driver);

PageLoader.get(driver, "forms.html");

Assert.assertFalse(page.checkBox.isChecked());
page.checkBox.check();
Assert.assertTrue(page.checkBox.isChecked());

driver.close();
}
}

资料来源:

Extend Selenium WebDriver WebElement?

http://elisarver.com/2012/12/09/wrapping-webelement-1/

http://elisarver.com/2012/12/10/wrapping-webelement-2

关于javascript - 如何从 WebdriverIO 中的 WebElement 继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54161944/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com