java - 如何在页面工厂模型中使用需要 'driver' 参数的函数/方法

标签 java selenium appium page-factory

在我的框架中,我有 baseTest 类和 BasePageObject 类 每个页面都扩展了 BasePO 事情是:我在页面上的很多方法都需要使用驱动程序实例。我有方法 getDriver() 并且我在每个页面上使用它“n”次 这导致 Appium 每 5 分钟 session 调用 getSession 120 次 因为我使用显式等待(参见代码):

[debug] [MJSONWP (ae82d29b)] Calling AppiumDriver.getSession() with args: ["ae82d29b-c0af-46f9-bb13-d6ecc8ff5a00"]
2019-10-10 03:22:45:681 - [debug] [XCUITest] Executing command 'getSession'

如何解决这个问题?

我不确定在不改变整个框架的情况下应该尝试什么

public class BasePO {

    WaitUtils waitUtils;
    AssertionUtils asrt;
    public BasePO() {
        asrt = new AssertionUtils();
        waitUtils = new WaitUtils();
        loadProperties();
        initElements();
    }
     private void initElements() {

        PageFactory.initElements(new AppiumFieldDecorator(getDriver()), this);
    }
    private void loadProperties() {

    }

    protected IOSDriver<IOSElement> getDriver() {
        return IOSDriverManager.getThreadLocalDriver();
    }
}

驱动程序管理器

public class IOSDriverManager {
    public static ThreadLocal<IOSDriver<IOSElement>> webDriver = new ThreadLocal<IOSDriver<IOSElement>>();

    public static DesiredCapabilities getIOSCaps() {
     Here Are my Caps
    }

    public static IOSDriver<IOSElement> getThreadLocalDriver() {
        IOSDriver<IOSElement> driver = webDriver.get();
        if (driver == null) {
            createThreadLocalWebDriver();
            driver = webDriver.get();
        }
        return driver;
    }

    public static void createThreadLocalWebDriver() {
        IOSDriver<IOSElement> driver = null;
             try {
                driver = new IOSDriver<IOSElement>(new URL("http://" + getProperty("accessUser") + ":" + getProperty("accessKey") + "@hub-cloud.browserstack.com/wd/hub"), getIOSCaps());
            } catch (Exception e) {
                try {
                    driver = new IOSDriver<IOSElement>(new URL("http://" + getProperty("accessUser") + ":" + getProperty("accessKey") + "@hub-cloud.browserstack.com/wd/hub"), getIOSCaps());
                } catch (MalformedURLException e1) {
                    System.out.println("IOS Driver is not created..!, Please check capabilitis or make sure Appium Server is running.");
                }
                return;
            }


        webDriver.set(driver);
    }

任何页面

public class dashboardPage extends BasePO {

    @iOSXCUITFindBy( id = "dashboardScreen")
    private MobileElement dashboardScreen;

  public boolean isDashboardScreen(){
        waitUtils.waitForElementToBeVisible(dashboardScreen, getDriver());
        boolean flag =dashboardScreen.isDisplayed();
        return flag;
    }

是否可以在不减少显式等待量的情况下减少 getSession 调用?

最佳答案

我通过在 BasePageObject 中添加一个 protected WebDriver 实例和一个 protected 构造函数(用于分配 WebDriver 实例)解决了自己框架中的问题。然后,您的其他 PageObject 继承自 BasePageObject,并且您可以为 PageObject 实现另一个以 WebDriver 作为参数的构造函数。

初始化 PageObjects 时,您可以将测试用例的 WebDriver 实例传递到 PageObject 中,这样您就不必一直调用 getDriver()。您可以使用此 WebDriver 实例在 PageObject 中执行操作,然后您的测试用例可以调用 PageObject 方法,而无需任何 getDriver()

这是我的 C# 框架的样子,从 BasePageObject 开始:

public class BasePageObject
{
    // protected WebDriver instance
    protected IOSDriver<IOSElement> Driver { get; }

    protected BasePageObject(IOSDriver<IOSElement> driver)
    {
        Driver = driver;
    }

然后,一个常规的 PageObject 表示为 SomePageObject:

// inherit from BasePageObject
public class SomePageObject : BasePageObject
{
    // implement protected constructor from BasePageObject
    public SomePageObject(IOSDriver<IOSElement> driver) : base(driver)
    {
    }

    // we can use the PageObject's driver instance as such
    public void DoSomethingWithDriver()
    {
        // this is protected WebDriver instance from BasePageObject above
        Driver.FindElement(SomeLocator);
    }
}

现在,将它们结合在一起,这是它在测试用例中的样子:

public class MyTestClass
{
    // initialize your driver somehow
    IOSDriver<IOSElement> driver = getThreadLocalDriver();

    // declare your PageObject, passing in your Driver instance
    SomePageObject myPageObject = new SomePageObject(driver);

    // now you can call PageObject methods as such
    myPageObject.DoSomethingWithDriver();
}

这一切都非常通用,需要进行修改以满足您的需求,但这是我在所有测试框架中遵循的设计模式,并取得了良好的结果。

关于java - 如何在页面工厂模型中使用需要 'driver' 参数的函数/方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58328456/

相关文章:

java - 如何使用 JAMA 将两个一维矩阵相乘?

java - 在 Android 中使用事件总线以及 Activity Lifecycle 方法和库实现

ios - Jenkins 无法打开 IOS 模拟器

java - 无法创建新的远程 session (Appium java 13)尝试启动应用程序

adb - 无法通过 ADB 启动应用程序我得到 "java.lang.SecurityException: Permission Denial: starting Intent"异常

Java Nimbus Look and Feel per component customization ("Nimbus.Overrides") - 其他实例也受影响

java - Gson - 无法从静态上下文引用非静态变量

selenium - PageFactory 中的 StaleElementReference 异常

java - innerhtml 中的对象未被 selenium webdriver 识别

java - 范围报告 3 添加屏幕截图