Java,Selenium和Method.invoke():出现NoSuchMethodException

huangapple go评论83阅读模式
英文:

Java, Selenium, and Method.invoke(): Getting NoSuchMethodException

问题

**目标**: 创建一个自己的方法调用传递给它的 Selenium 方法并重复执行该方法指定的次数

**问题**: 无论我尝试什么以下代码始终会产生错误:
java.lang.NoSuchMethodException: org.openqa.selenium.WebDriver.sendKeys()

**讨论**: 据我所知sendKeys() 是 org.openqa.selenium.WebDriver 内的一个方法

有问题的代码:

Method objTest = WebDriver.class.getMethod(strMethod, CharSequence.class);

其中 strMethod = sendKeys

**代码**

    public void repeatAction(String strMethod, int numberOfTimes) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		int i = 0;
		Method objTest = WebDriver.class.getMethod(strMethod, CharSequence.class); // 问题代码 - 导致 NoSuchMethodException
		while (i <= numberOfTimes) {
			objTest.invoke(strMethod, Keys.DOWN);  // 我现在已经将 Keys.DOWN 硬编码,但稍后会使其更加灵活
			i++;
		}
	}

我在 main() 中调用了 repeatAction() 方法:

    AutocompleteDropdownPractice objADDP = new AutocompleteDropdownPractice();
    objADDP.repeatAction("sendKeys", 5);     // 重复执行 Selenium WebDriver 的 sendKeys() 方法 5 次

**运行时错误**

    Exception in thread "main" java.lang.NoSuchMethodException: org.openqa.selenium.WebDriver.sendKeys(java.lang.CharSequence)
	at java.base/java.lang.Class.getMethod(Class.java:2109)
	at AutocompleteDropdownPractice.repeatKeysAction(AutocompleteDropdownPractice.java:17)
	at AutocompleteDropdownPractice.main(AutocompleteDropdownPractice.java:45)

如果您对我做错了什么以及应该如何做有任何帮助将不胜感激
英文:

Goal: Create my own method that calls the Selenium method passed into it and repeats that method a specified number of times.

Problem: No matter what I try, the following code ALWAYS results in:
java.lang.NoSuchMethodException: org.openqa.selenium.WebDriver.sendKeys()

Discussion: As far as I know sendKeys() exists as a method within/of org.openqa.selenium.WebDriver

Problem code:

Method objTest = WebDriver.class.getMethod(strMethod, CharSequence.class);

Where strMethod = sendKeys

Code

public void repeatAction(String strMethod, int numberOfTimes) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
int i = 0;
Method objTest = WebDriver.class.getMethod(strMethod, CharSequence.class); // PROBLEM CODE - results in NoSuchMethodException
while (i &lt;= numberOfTimes) {
objTest.invoke(strMethod, Keys.DOWN);  // I&#39;ve hardcoded Keys.DOWN for now but will make this flexible later
i++;
}
}

I call my repeatAction() method in main():

AutocompleteDropdownPractice objADDP = new AutocompleteDropdownPractice();
objADDP.repeatAction(&quot;sendKeys&quot;, 5);     // Repeat Selenium WebDriver&#39;s sendKeys() 5 times

Runtime Error

Exception in thread &quot;main&quot; java.lang.NoSuchMethodException: org.openqa.selenium.WebDriver.sendKeys(java.lang.CharSequence)
at java.base/java.lang.Class.getMethod(Class.java:2109)
at AutocompleteDropdownPractice.repeatKeysAction(AutocompleteDropdownPractice.java:17)
at AutocompleteDropdownPractice.main(AutocompleteDropdownPractice.java:45)

Any assistance as to what I'm doing incorrectly and how I should be doing it will be greatly appreciated.

答案1

得分: 1

如果您查看Selenium API,您会发现WebDriver类没有sendKeys()方法,这正是您收到NoSuchMethodException的原因。

我认为您正在寻找org.openqa.selenium.WebElement.sendKeys(java.lang.CharSequence... keysToSend)方法,在您的情况下,您可以按以下方式使用它:

Method objTest = WebElement.class.getMethod(strMethod, CharSequence[].class);

我使用了数组版本的CharSequence[].class,而不是CharSequence.class,因为sendKeys方法接受CharSequence.class的数组,这在API文档中可以清楚地看到。

英文:

If you look at the Selenium API you'll see that there isn't any method of WebDriver class as sendKeys() and that is the very reason why you are getting the NoSuchMethodException.

I think you were looking for the org.openqa.selenium.WebElement.sendKeys(java.lang.CharSequence... keysToSend) method, which in your case you could use it as follows:

Method objTest = WebElement.class.getMethod(strMethod, CharSequence[].class);

I used the array version CharSequence[].class instead of CharSequence.class because the sendKeys method accepts an array of CharSequence.class which can be clearly seen in the API docs.

答案2

得分: 0

First

如果你查阅Java文档,你会看到 invoke() 方法 接受两个参数:

  1. 从中调用方法的对象(因为你需要对象来调用非静态方法)
  2. 方法参数

你的示例中的这些代码行:

Method objTest = WebDriver.class.getMethod(strMethod, CharSequence.class);
objTest.invoke(strMethod, Keys.DOWN);

意味着你从 WebDriver 类中获取方法,并在 String 对象上调用它,这是不正确的。

Second

sendKeys 方法是在 WebElement 接口中声明的,而不是在 WebDriver 中。

Third

你尝试的操作可以使用 Proxy 对象来完成,如下所示:

public WebElement poxiedElement(String methodName, int times, WebElement element){
    return (WebElement) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{WebElement.class}, new InvocationHandler() {
        @Override
        public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
            Object[] results = new Object[times];
            if(methodName.equals(method.getName())){
                for(int i = 0; i < times; i++){
                    results[i] = method.invoke(element, objects);
                }
            }
            return results;
        }
    });
}

void test(){
    WebElement element = driver.findElement(By.xpath("..."));
    poxiedElement("sendKeys", 5, element).sendKeys("blah");
}

P.S. - 你应该明白一个方法可以返回一个值。因此,多次调用任何方法可能会返回多个值。你必须考虑到这一点。在我的示例中,该方法将返回结果的数组。

英文:

First

If you refer to Java documentation you will see that invoke() method takes two parameters:

  1. Object that you invoke a method from (since you need the object to invoke non-static method)
  2. Method arguments

These lines in your example:

Method objTest = WebDriver.class.getMethod(strMethod, CharSequence.class);
objTest.invoke(strMethod, Keys.DOWN);

mean that you take method from WebDriver class and invoke it on String object which is incorrect.

Second

sendKeys method is declared in WebElement interface, not in WebDriver.

Third

What you are trying to do can be done with Proxy objects like shown here:

public WebElement poxiedElement(String methodName, int times, WebElement element){
    return (WebElement) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{WebElement.class}, new InvocationHandler() {
        @Override
        public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
            Object[] results = new Object[times];
            if(methodName.equals(method.getName())){
                for(int i = 0; i &lt; times; i++){
                    results[i] = method.invoke(element, objects);
                }
            }
            return results;
        }
    });
}

void test(){
    WebElement element = driver.findElement(By.xpath(&quot;...&quot;));
    poxiedElement(&quot;sendKeys&quot;, 5, element).sendKeys(&quot;blah&quot;);
}

P.S. - You should understand that a method can return a value. So calling any method several times might return several values. You have to consider this. In my example the method will return array of results.

huangapple
  • 本文由 发表于 2020年10月8日 03:38:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/64251166.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定