简体   繁体   English

从超类型对象创建红宝石对象

[英]Create a ruby object from a supertype object

I am using the Selenium Webdriver libraries in Ruby. 我在Ruby中使用Selenium Webdriver库。 A typical piece of code looks like this: 典型的代码如下:

require 'rubygems'
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox 
# driver is an instance of Selenium::WebDriver::Driver

url = 'http://www.google.com/'
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
driver.get(url)
wait.until { driver.title.start_with? "Google" }

I would like to create a subclass of Selenium::WebDriver::Driver called Selenium::WebDriver::Driver::MyClass that will contain some new methods and instance variables. 我想创建一个名为Selenium::WebDriver::Driver::MyClassSelenium::WebDriver::Driver子类,它将包含一些新方法和实例变量。

As the above code illustrates, the way that instances of Selenium::WebDriver::Driver are created is with Selenium::WebDriver.for . 如上面的代码所示,创建Selenium::WebDriver::Driver实例的方式是使用Selenium::WebDriver.for

Without wholesale copying of code, how can I create a version of Selenium::WebDriver.for that does the same thing as Selenium::WebDriver.for but creates instances of Selenium::WebDriver::Driver::MyClass ? 如果没有代码复制批发,我怎么能创建一个版本的Selenium::WebDriver.for ,做同样的事情Selenium::WebDriver.for而造成的情况下, Selenium::WebDriver::Driver::MyClass

Why not just override the Selenium::WebDriver.for ? 为什么不仅仅覆盖Selenium::WebDriver.for let me show you that my an example 让我告诉你我的例子

# selenium code
module Selenium
  class WebDriver
    def self.for
      puts "creating oldclass"
    end
  end
end

# your code
class Selenium::WebDriver
  def self.for
    puts "creating myclass"
  end
end

Selenium::WebDriver.for

output: 输出:

creating myclass

Safe alternative is to derive class from Selenium::WebDriver and use that in your code, or to the extreme you can just open Driver class and add your behavior to it. 安全的替代方法是从Selenium::WebDriver派生类并在代码中使用它,或者极端地,您可以打开Driver类并将其行为添加到其中。

Check the source code . 检查源代码 Selenium::WebDriver.for simply delegate the method call to Selenium::WebDriver::Driver.for . Selenium::WebDriver.for只需将方法调用委托给Selenium::WebDriver::Driver.for

If you don't have listener attached, you can simple create your own bridge MyClass::Bridge.new and then pass that to Selenium::WebDriver::Driver.new . 如果没有连接侦听器,则可以简单地创建自己的桥MyClass::Bridge.new ,然后将其传递给Selenium::WebDriver::Driver.new

If you insist override the for method, here is some code snippet that might help. 如果您坚持要覆盖for方法,则以下一些代码段可能会有所帮助。

module Selenium
  module WebDriver
    class Driver
      class << self
        alias_method :old_for, :for
        def for(browser, opts = {})
          if browser == :myclass
            # create your MyClass::Bridge instance and pass that to new()
          else
            old_for(browser, opts)
          end
        end
      end
    end
  end
end

If you just want to define some extra methods on your driver, you do not need to override WebDriver.for. 如果只想在驱动程序上定义一些其他方法,则无需覆盖WebDriver.for。

The following worked well for me: 以下对我来说很有效:

First, in file customdriver.rb 首先,在文件customdriver.rb中

require 'selenium-webdriver'
class CustomDriver < Selenium::WebDriver::Driver 
  #a custom method..
  def click_on (_id)
    element = find_element :id => _id
    element.click
  end 
  #add other custom methods here
  #....
end

Then, in file main.rb 然后,在文件main.rb中

require-relative 'customdriver'
driver = CustomDriver.for :chrome
driver.click_on("buttonID")

Regards, 问候,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM