英文:
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 <= numberOfTimes) {
objTest.invoke(strMethod, Keys.DOWN); // I'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("sendKeys", 5); // Repeat Selenium WebDriver's sendKeys() 5 times
Runtime Error
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)
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() 方法 接受两个参数:
- 从中调用方法的对象(因为你需要对象来调用非静态方法)
- 方法参数
你的示例中的这些代码行:
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:
- Object that you invoke a method from (since you need the object to invoke non-static method)
- 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 < 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. - 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论