我正在阅读Webdriver项目网站上的页面对象和设计模式,并遇到了pagefactory.它看起来不像Python API的Webdriver包含pagefactory.这是真的?
是否可以使用页面对象gem和capybara来自动化Ruby on Rails测试?当我在启动测试后尝试访问页面对象时,收到以下错误:
Unable to pick a platform for the provided browser (RuntimeError)
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为我认为我必须将capybara的浏览器实例传递给页面对象,不确定是否有其他人曾经尝试过这个.
ruby-on-rails capybara pageobjects page-object-gem selenium-webdriver
我使用Page Object Pattern with Java(https://code.google.com/p/selenium/wiki/PageObjects)构建了各种Test Automation框架.
我发现的两大好处是:
1)当你有一个页面实例时,你可以看到可用的方法(例如,输入主页.将显示你可以从主页调用的所有动作/方法)
2)因为导航方法(例如goToHomepage())返回后续页面的实例(例如主页),所以您只需编写代码并查看它所在的位置即可浏览您的测试.
例如
WelcomePage welcomePage = loginPage.loginWithValidUser(validUser);
PaymentsPage paymentsPage = welcomePage.goToPaymentsPage();
Run Code Online (Sandbox Code Playgroud)
这些好处与Java完美配合,因为IDE已知对象类型(或本例中的页面).
但是,使用JavaScript(动态类型语言),对象类型在任何时候都不固定,并且通常与IDE不明确.因此,我无法看到如何在使用JavaScript构建的自动化套件中实现这些优势(例如,使用Cucumber).
任何人都可以告诉我如何使用页面对象模式的JavaScript来获得这些好处吗?
我很少去幻想和写硒页面对象与Java 8流,如下面的代码中提到并得到了我的代码是打破得墨忒耳定律,因为我在一行做很多操作的审查意见.我被建议将代码分解为第一个流来收集列表并运行另一个流操作来进行匹配(简而言之,根据需要将其分解为多个流).我不相信Stream是用于处理数据处理的,如果我们将其分解为多个流,那么使用流是没有意义的.在此之前,我曾参与过网络安全项目,数百万条记录通过流媒体处理,并通过多种逻辑操作对数据进行排序.
请分享您的想法,我已经按照审稿人的建议对其进行了更改,但他无法解释原因,我想了解更多关于流和正确利用这一强大的java 8补充方法的方法.
以下是示例代码:
listOfWebElements.stream().filter(element -> element.getText().contains(name)).findFirst().ifPresent(match -> match.click());
Run Code Online (Sandbox Code Playgroud)
我在这个问题中指的是这条线,提供方法使它更有意义.
@FindBy(css = "#someTable td.some-name li a") List<WebElement> listOfWebElements;
public SomeClass doSomething(String name) {
wait.until(visibilityOfAllElements(listOfWebElements));
listOfWebElements.stream().filter(element -> element.getText().contains(name)).findFirst()
.ifPresent(match -> match.click());
return new SomeClass(driver);
}
Run Code Online (Sandbox Code Playgroud) 这是一个我无法找到确切来源的问题,希望基于用户以前的经验获得一些答案,主要是解释为什么某种方法无法解决。
我正在通过Protractor使用webdriver进行自动化,并且正在争论是否应在页面对象本身之外使页面元素可用。经过研究,人们似乎采取了几种不同的方法,但我无法完全掌握每种方法的长期含义。
我已经看到页面对象模型的以下不同实现:
这是我最不喜欢的方法,因为这意味着在测试中实际上已识别出元素。设置这似乎是一个糟糕的标准,因为它可能会鼓励自动化人员直接在应用程序中使用新的定位器,而不是页面对象。同样,在初始化PO时,不能直接设置任何需要动态信息的参数,需要进一步编辑。
pageobject.js
export default class HomePage {
constructor() {
this.passwordField = '#password';
this.usernameField = '#user';
}
}
Run Code Online (Sandbox Code Playgroud)
test.js
const homePage = new HomePage();
$(homePage.usernameField ).sendKeys('admin');
$(homePage.passwordField ).sendKeys('password');
Run Code Online (Sandbox Code Playgroud)
pageobject.js
export default class HomePage {
constructor() {
this.passwordField = $('#password');
this.usernameField = $('#user');
}
}
Run Code Online (Sandbox Code Playgroud)
test.js
const homePage = new HomePage();
homePage.usernameField.sendKeys('admin);
homePage.passwordField.sendKeys('password);
Run Code Online (Sandbox Code Playgroud)
这是我过去使用的方法,最终我们获得了许多功能。例如setUsename(), getCurrentUsername(), getUsernameAttibute(), verifyUsernameExists()
,password
元素和许多其他元素具有和。我们的页面对象变得巨大,所以我觉得这不再是最好的方法。但是,优点之一是我们的测试看起来很干净而且可读性很强。
pageobject.js
export default class HomePage {
constructor() {
var passwordField= $('#password');
var usernameField …
Run Code Online (Sandbox Code Playgroud) automated-tests webdriver pageobjects selenium-webdriver protractor
我一直在使用Selenium WebDriver为我曾经使用过的一些项目实现功能测试.我正在尝试使用Page Factory设计模式与Page Factory来分解我的定位器.我还创建了一个静态WaitTool对象(singleton),它使用可选的超时参数实现了几种等待技术.
我目前的问题是我想在PageFactory尝试初始化WebElements之前使用我的wait方法.我想等待的原因是因为PageFactory可能会尝试在页面元素可用之前初始化页面元素.
这是一个示例PageObject:
public class SignInPage extends PageBase {
@FindBy(id = "username")
@CacheLookup
private WebElement usernameField;
@FindBy(id = "password")
@CacheLookup
private WebElement passwordField;
@FindBy(name = "submit")
@CacheLookup
private WebElement signInButton;
public SignInPage(WebDriver driver) {
super(driver);
WaitTool.waitForPageToLoad(driver, this);
// I'd like initialisation to occur here
}
public MainPage signInWithValidCredentials(String username, String password){
return signIn(username, password, MainPage.class);
}
private <T>T signIn(String username, String password, Class<T> expectedPage) {
usernameField.type(username);
passwordField.type(password);
signInButton.click();
return PageFactory.initElements(driver, expectedPage);
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个示例TestObject:
public class SignInTest …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用页面工厂@FindBy
注释在Selenium Webdriver中编写页面对象.页面对象用于侧边栏,包含页面对象需要与之交互的所有元素的父WebElement以这种方式初始化:
@FindBy (xpath = "//div[contains(@class,'yui3-accordion-panel-content') and child::div[.='Sidebar']]")
WebElement sidebar;
Run Code Online (Sandbox Code Playgroud)
然后我想要相对于这个sidebar
元素的搜索输入.有没有办法做这个引用sidebar
元素?我可以将整个路径复制并粘贴到开头:
@FindBy (xpath = "//div[contains(@class,'yui3-accordion-panel-content') and child::div[.='Sidebar']]//input[@id='search']")
Run Code Online (Sandbox Code Playgroud)
但我宁愿相对于第一个元素.有可能这样吗?
@FindBy (parent = "sidebar", xpath = ".//input[@id='search']")
Run Code Online (Sandbox Code Playgroud)
关于@FindBy注释的Selenium文档有点缺乏......
我是一名相对较新的QA工程师,致力于学习Selenium(Java),我想使用页面对象来模拟我的页面.
目前,我正在这样做,我的页面对象类是静态变量(用于定位页面元素的对象)和静态方法(用于获取By对象和执行页面函数)的集合.这对我来说似乎是最简单的方法,因为我的方法不需要依赖任何实例变量,只需要依赖定位器.
我只是在我的测试代码中调用这些方法.
但是,我读到的关于页面对象的所有内容都涉及实例化它们并让方法返回页面对象.这似乎让一切变得更加复杂.例如,我没有一个登录方法,而是需要两个,一个用于登录成功,一个用于登录失败.
我知道它似乎是公认的最佳实践,但我想了解原因.谢谢.
这是我的pageObject代码,我的测试调用方法为 LoginPage.login(username, password);
package pageObjects;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class LogInPage {
private static By emailTxtB = By.id("user_email");
private static By passwordTxtB = By.id("user_password");
private static By logInButton =
By.xpath("/html/body/div/div[2]/form/div[2]/div[2]/div/button");
private static By signUpButton = By.xpath("/html/body/div/div[2]/form/div[2]/div[2]/div/a");
private static By valErrorMessage = By.id("flash_alert");
public static void logIn(WebDriver driver, String email, String password){
//Fill out form
driver.findElement(emailTxtB).sendKeys(email);
driver.findElement(passwordTxtB).sendKeys(password);
//Submit form
driver.findElement(logInButton).click();
}
public static void goToSignUp(WebDriver driver){
driver.findElement(signUpButton).click();
}
public static String getValErrorMessage(WebDriver driver){
return driver.findElement(valErrorMessage).getText(); …
Run Code Online (Sandbox Code Playgroud) 我所有的页面对象看起来像这样:
elements: {
header: {
locateStrategy: 'xpath',
selector: "//h3[text()='Welcome']"
},
loginButton: {
locateStrategy: 'xpath',
selector: "//button[text()='Login']"
},
forgotPasswordLink: {
locateStrategy: 'xpath',
selector: "//a[text()='Forgot Password?']"
},
signupButton: {
locateStrategy: 'xpath',
selector: "//button[text()='Signup']"
}
Run Code Online (Sandbox Code Playgroud)
如果我能说“在任何地方使用 xpath”,那就更好了——这一切都会崩溃
文档说你应该能够"use_xpath" : true
在你的“测试设置”中进行设置,但我已经在 nightwatch.json 中可以看到的所有地方都试过了,但它没有任何效果。
(在任何情况下,它们是否意味着此设置会影响页面目标文件中的声明尚不完全清楚:该示例仅显示它会影响测试用例中的后续断言调用)。
是否可以要求结构具有特定字段作为特征的一部分?我正在使用 Rust 中的 Thirdfour_sync 箱进行一些网络自动化。我想为将实现它们的页面对象编写一些具有默认实现的特征。基本上,我知道每个要实现此特征的结构都会有一个名为“driver”的字段,该字段保存对 WebDriver 结构的引用。我想在该特征的默认实现中使用此驱动程序字段。
error[E0609]: no field `driver` on type `&Self`
--> src\base_order_details.rs:13:30
|
10 | / pub trait BaseOrderDetails {
11 | |
12 | | fn oid(&self) -> WebDriverResult<String> {
13 | | let oid_title = self.driver.find_element(By::XPath("//*[text()=\"Order ID:\"]"))?;
| | ^^^^^^
... |
Run Code Online (Sandbox Code Playgroud)
有没有办法让编译器知道任何实现此特征的东西都将具有 &WebDriver 类型的字段驱动程序?
pageobjects ×10
java ×5
selenium ×3
webdriver ×3
capybara ×1
java-stream ×1
javascript ×1
protractor ×1
python ×1
rust ×1
struct ×1
testing ×1
traits ×1
xpath ×1