我有一个selenium测试(确切地说,是selenide),其中这个场景需要文件上传。我要上传文件的元素是,一个隐藏的输入字段,位于DOM的末尾;
<input type="file" style="height: 0; width: 0; visibility: hidden;" tabindex="-1" accept="*">
只有在单击文件应该从系统中“拖放”或加载的区域后才会出现;
<a class="browse" ref="fileBrowse" href="#">select files...</a>
这意味着,如果不需要首先单击元素(例如,sendKeys、uploadFile、uploadFromClassPath等),我就无法使用到到目前为止所知道的任何方法。然而,只要单击元素,就会出现一个对话框窗口。加载文件后,该窗口将不会关闭,而且我还没有找到关闭该窗口的健壮解决方案。
我使用的是macOS和chrome,这意味着我不能使用"autoIT",我也不能运行"sikuliX“来创建一个简单的屏幕截图脚本。
然而,我能够使用Automator来抢占一个applescript,只要我们省略web驱动程序的实例存在,它就能工作得很好。意思是,如果我从控制台运行脚本,设置网站就像自动测试所发现的一样--它可以工作.不幸的是,一旦测试在webdriver中实例化和运行,它就无法工作。
我有两个问题--我希望有更多经验的人能回答:
( 1)如何使applescript使用webdriver实例而不是常规的chrome窗口--如果这个问题得到解决,它是一个非常好的解决方案
2)关于如何关闭“上传”对话框窗口的其他想法吗?
applescript
on run {input, parameters}
-- Click “Google Chrome” in the Dock.
delay 6.006100
set timeoutSeconds to 2.000000
set uiScript to "click UI Element \"Google Chrome\" of list 1 of application process \"Dock\""
my doWithTimeout( uiScript, timeoutSeconds )
return input
-- Click the ÒCancelÓ button.
delay 3.763318
set timeoutSeconds to 2.0
set uiScript to "click UI Element \"Cancel\" of sheet 1 of window \"PowerFLOW portal - Google Chrome\" of application process \"Chrome\""
my doWithTimeout(uiScript, timeoutSeconds)
return input
end run
on doWithTimeout(uiScript, timeoutSeconds)
set endDate to (current date) + timeoutSeconds
repeat
try
run script "tell application \"System Events\"
" & uiScript & "
end tell"
exit repeat
on error errorMessage
if ((current date) > endDate) then
error "Can not " & uiScript
end if
end try
end repeat
end doWithTimeout用于在测试中运行脚本的代码。
try {
new ProcessBuilder("/path/to/the/script").start();
} catch (IOException e) {
e.printStackTrace();
}
}除了尝试使用applescript之外,我还尝试过"java机器人类“,但是我无法关闭对话框窗口。
使用下面的片段,未注释的部分会转义整个铬窗口(窗口变为“灰色”/inactive),而不是对话框窗口,老实说,这让我感到惊讶,因为当时我认为对话框窗口是主要的工作窗口。
被注释的部分可以工作,但是正如您可以想象的那样,如果测试在任何其他机器上运行,那么它是无用的,因为坐标只适用于我的机器。
try {
Robot robot = new Robot();
//robot.mouseMove(906, 526);
//robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
//robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
robot.keyPress(KeyEvent.VK_ESCAPE);
robot.keyRelease(KeyEvent.VK_ESCAPE);
} catch (AWTException e) {
e.printStackTrace();
}这个方法本身看起来就像这样
$$x("#ElementsCollection")
.findBy("text1")
.scrollIntoView(true)
.find(byXpath("#xpath")).val("text2")
.find(byXpath("#xpath") //this is the location of the <a> element mentioned above that needs to be clicked in order for <input type file> element to appear
.click();
$x("//input[@type=\"file\"]").sendKeys("/path/to/the/uploadedFile");发布于 2021-10-19 12:42:31
正如我所见,在实现目标的过程中,最初的复杂性是
该文件是一个隐藏的输入字段,只有在单击文件应该从系统中“拖放”或加载的区域后才会出现;
也就是说-隐藏的文件。如果我错了,请纠正我:)
但这不应该是问题所在,因为的sendKeys命令可以使用type=file输入标记的隐藏元素。因此,简单的sendKeys应该通过。Selenide的uploadFromClassPath命令是基于原始的sendKeys -所以它也应该通过。
下面是一个简单的测试,它表明上传文件不依赖于输入元素的可见性:
import org.junit.jupiter.api.Test;
import static com.codeborne.selenide.Condition.hidden;
import static com.codeborne.selenide.Condition.text;
import static com.codeborne.selenide.Selenide.*;
import static com.codeborne.selenide.Selenide.$;
public class TheInternetTest {
@Test
void fileUpload() {
// GIVEN
open("https://the-internet.herokuapp.com/upload");
executeJavaScript(
"document.getElementById('file-upload').style.display = 'none'"
);
$("#file-upload").shouldBe(hidden);
// WHEN
$("#file-upload").uploadFromClasspath("temp.txt");
$("#file-submit").click();
// THEN
$("#uploaded-files").shouldHave(text("temp.txt"));
}
}使用以下代码检查完整的工作项目:https://github.com/yashaka/selenide-file-upload-demo/blob/main/src/test/java/TheInternetTest.java
在编写Web测试时,常见的最佳实践是“找到实现目标的简单方法,而不是真实用户模拟的最佳方式”。这就是为什么我们试图绕过所有被测试应用程序无法控制的窗口。因此,我的建议是-忘记苹果脚本,直接通过selenium处理输入文件。
https://stackoverflow.com/questions/69382890
复制相似问题