【问题标题】:Mink/behat iframe without id/name没有 ID/名称的 Mink/behat iframe
【发布时间】:2016-07-29 20:43:26
【问题描述】:

我必须在没有名称/ID 的情况下验证 iframe 中的文本/消息。经过探索,我发现了添加 id/name 并使用 switchToIFrame(id/name) 的解决方案。如何将 id/name 设置为 mink 中的节点元素?节点元素中不支持 SetAttribute() 方法,并且帧不支持 setValue()。

<html>
  <body>
    <div class="div1">
    <iframe class="xyz">
      <!DOCTYPE html>
      <html>
        <body>
          <div class="frame"></div>
          <p>The paragraph1</p>
        </body>
       </html>
  </body>
</html>

我的上下文文件是

public function iShouldSeeDescription($arg1)
{
    $expected = "The paragraph1";
    $iframe=$this->getSession ()->getPage ()->find ( 'xpath', '//div[contains(@class,"div1")]/iframe[contains(@class,"xyz")]');
    $iframe->setAttribute('id', 'iframe_id');
    $iframeId = $iframe->getAttribute('id');
    $this->getSession()->switchToIframe("$iframeId");
    $actual = $this->getSession()->getPage()->find('xpath', '//div[@class="frame"]/p[1]');
    if ($actual === null) {
        throw new \InvalidArgumentException ( sprintf ( 'null:%s', $arg1 ) );
    }
    if (!($actual === $expected)) {
        throw new \InvalidArgumentException ( sprintf ( 'The Acutal description:%s and expected description:%s did not match ', $actual, $expected ) );
    }

}

【问题讨论】:

  • 我假设这只是一种测试方法,否则切换到 iframe 和验证应该是不同的步骤,预期的文本和包含此文本的选择器应该是方法的参数。

标签: iframe behat mink setattribute


【解决方案1】:

将 id/name 设置为 iframe 的方法是使用 javascript。

创建一个类似于 switchToIFrameBySelector($iframeSelector) 的方法,它等待给定的元素可用,然后您可以执行一段 javascript 代码为您的 iframe 设置名称/ID,然后使用 switchToIFrame 方法。

为了执行 js 脚本,您可以在 try-catch 中使用 executeScript 方法,并在需要时抛出自定义异常。

public function switchToIFrame($iframeSelector){

        $function = <<<JS
            (function(){
                 var iframe = document.querySelector("$iframeSelector");
                 iframe.name = "iframeToSwitchTo";
            })()
JS;
        try{
            $this->getSession()->executeScript($function);
        }catch (Exception $e){
            print_r($e->getMessage());
            throw new \Exception("Element $iframeSelector was NOT found.".PHP_EOL . $e->getMessage());
        }

        $this->getSession()->getDriver()->switchToIFrame("iframeToSwitchTo");
    }

另一种在js中设置元素id/name的方法是使用:

setAttribute('name', 'iframeToSwitchTo')

【讨论】:

  • 我从您的其他 Stackoverflow 答案中找到了这个解决方案。有没有办法在 PHP 中做到这一点?
  • 不使用 js/jQuery 我不这么认为。我看到有一个方法 setValue 指向 Selenium2Driver,它也使用 js 脚本。也许没有方法可以更改页面/元素,因为您不应该进行这些类型的更改,setValue 用于设置文本字段的值/输入。使用js有什么限制吗?您应该只与页面交互而不是更改它,使用 js 是一种解决特殊情况的方法。如果可能,您应该与项目的开发人员交谈以添加一些属性。
  • 我会尝试使用这个解决方案,看看我的问题是否得到解决。在我成功后,我也会发布我的代码。谢谢!
  • 效果很好,谢谢。
  • 公共函数 iSwitchToIframe($arg1) { $function = getSession()->executeScript($function); $this->getSession()->getDriver()->switchToIFrame("iframeToSwitchTo"); } catch (Exception $e){ throw new \InvalidArgumentException ( sprintf ("caught exception: %s", $e->getMessage())); } }
【解决方案2】:

输入数字或for循环来迭代需要哪个然后设置数字与交叉原点一起使用

$this->getSession()->getDriver()->switchToIFrame(0);

【讨论】:

  • 这不是这个方法的工作原理。当您查看实现时,参数必须是用于搜索命名 iFrame 的字符串。此解决方案会导致错误。
猜你喜欢
  • 1970-01-01
  • 2013-05-02
  • 2013-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-25
相关资源
最近更新 更多