clevis/se34

Selenium测试的辅助类。

1.0.3 2014-06-05 09:59 UTC

This package is not auto-updated.

Last update: 2024-09-23 14:28:04 UTC


README

这份README非常过时,我正在准备更好的文档。

这份README已经过时,即将提供更好的文档。

此库依赖于

  • Nette
  • PHPUnit
  • PHPUnit_Selenium

在每个项目中都需要创建这些特定于项目的类

  • SeleniumConfigurator - 创建系统容器和测试数据库。
  • SeleniumRouteList - 为每个URL添加一个名为所使用数据库的参数。
  • SeleniumTemplateFactory - 重新设置$baseUrl,以便静态文件链接指向正常的根目录。
  • SeleniumTestCase extends Se34\TestCase - 必须实现createContext()

由SeleniumConfigurator创建的系统容器必须提供以下参数

parameters:
	selenium:
		server: http://localhost:4444
		desiredCapabilities
			browserName: firefox
		baseUrl: http://localhost/projekt/test-www/
		# keepWindowOpenOnFailure: FALSE # Volitelné, výchozí hodnota je TRUE.

接下来需要创建一个替代根(测试将通过它访问应用程序)

  • index.php - 实际上是普通的引导,但使用SeleniumConfigurator。
  • tmp
  • .htaccess - 从根目录复制并粘贴,但添加Deny from allAllow from 127.0.0.1

Selenium服务器

要运行测试,需要

  • Java。
  • Selenium服务器
  • 要运行除Firefox之外的其他浏览器(可以在tests/inc/selenium.neon中设置)

在启动实际测试之前,必须启动Selenium服务器,理想情况下是从命令行启动(因为这样可以通过ctrl-c轻松终止)

java -jar selenium-server-standalone-2.25.0.jar

这个库允许在测试完成后保留浏览器窗口打开(这在出错时很有用)。在这种情况下,但是Chrome Driver进程将保留在内存中(其他驱动程序也可能这样做)。经过一段时间,它们可能会堆积起来并减慢速度,在Windows上可以使用taskkill /F /IM chrome-driver.exe终止它们。

访问Selenium命令

基本类提供了一个会话对象,通过该对象调用Selenium命令

public function testFoo()
{
	$this->session->byXpath('//button[text()="Text"]')->click();
}

我之前尝试过PHPUnit_Extensions_Selenium2TestCase,在其中可以通过$this访问一切,但我认为这很糟糕。

Selenium 2 (WebDriver)

测试使用Selenium 2。与Selenium 1的主要区别

  • 不同的API,更面向对象。在$session->type('name', 'value')的位置,写入$session->byName('name')->value('value') - 即先选择元素,然后再对其进行操作。如果元素未找到,将抛出RuntimeException。
  • 执行命令更接近用户的行为。例如
    • 元素对象的value命令不会直接覆盖其javascript属性的value,而是将焦点传递给元素并模拟按键。因此,例如
      • 可以使用回车键提交表单。
      • 可以通过输入前几个字符从选择中选择。
      • 将执行附加在按键上的任何JS事件。
    • 如果元素不可见,则无法点击它。如果某些菜单在鼠标悬停在另一个元素上后才展开,则需要首先悬停在元素上(例如,$session->moveto($session->byLinkText('Menu')))。
    • 同样,如果整个页面被开发者工具覆盖,则无法点击任何内容(就像在现实中一样)。不过,BrowserSession通常可以捕获这些开发者工具。

WebDriver API

WebDriver API 指令文档在此:[http://code.google.com/p/selenium/wiki/JsonWireProtocol](http://code.google.com/p/selenium/wiki/JsonWireProtocol)

WebDriver API 中的指令,BrowserSession 目前尚未提供,但可以非常容易地添加(通过 BrowserSession::initCommands())。

WaitForAjax 等。

Session 对象提供了一些等待方法

  • waitForAlert() - 如果页面上有传统的 JS 对话框(alert、confirm 或 prompt),则大多数命令会因为错误而结束。但是,在 alert 出现之前,alertText 命令也会因为错误而结束。因此,这个方法会一直执行 alertText,直到它成功结束。然后可以继续与对话框交互
    • alertText($text) - 将文本插入到提示框中。
    • acceptAlert() - 确认对话框。
    • dismissAlert() - 取消对话框。
  • waitForCondition($condition) - 等待某个 JS 条件满足。
  • waitForDocument() - 等待 document.readyState == "complete"
  • waitForAjax() - 等待 jQuery.active == 0

断言

Se34\TestCase 添加了这些断言

  • assertPresenter
  • assertTagName
  • assertTagAttributes
  • assertElementEquals

页面对象

为了使测试不那么依赖于当前的 HTML 代码,建议使用所谓的“页面对象”。有关页面对象设计模式的文章

页面对象的基类

Se34\PageObject

  • 支持注解
    • @property-read - 访问元素的缩写。
    • @method - 对元素执行操作的函数。
  • 执行状态检查。
    • 通过缩写访问元素。
    • 调用魔法方法。
    • 在请求时(通过 ->checkState())。

示例:todo

@property-read 格式

/**
 * @property-read Element $searchBox name=q, input, (type=text) # Poznámka
 * @property-read Element[] $allLinks xpath='//a', a # Příklad na pole elementů
 */
  • @property-read
  • Element - 如果是 Element[](或 Cokoli[]),则表示所有符合该标准的元素数组,否则表示一个元素。
  • $searchBox - 缩写名称,不要忘记 $
  • name = q - 定位策略 = 值
  • input - 可选。如果指定,将检查找到的元素/元素的名称。
  • (type = text) - 可选。如果指定,将检查属性的值。
  • # 注释 - 可以使用空格和斜杠分隔注释。

在属性名称和注释之间的部分将被 Neon 解析。

@method 格式

/**
 * @method ReturnType methodShortcut() Description
 */
  • @method

  • ReturnType - 返回类型,必须实现 Se34\IPageObject。如果不在反引号内,则首先在定义该注解的类(即包含该 @method 注解的类)的命名空间中查找。

    如果 $this instanceof ReturnType,则直接返回 $this

  • methodShortcut - 将 $page->methodShortcut($arg) 的调用转换为 $page->shortcut->method($arg),区别在于返回值。

getNextPage()

@method 注解不足以选择下一个页面对象时,可以使用这个受保护的函数

/**
 * @return AnotherPage|YetAnotherPage Možné návratové typy.
 */
public function clickSomething()
{
	$this->something->click();
	$this->session->waitForAjax();
	return $this->getNextPage(); // vybírá z typů v @return
}

fill()

填充表单的辅助魔法。

$page->fillFoo($value); // $page->foo->value($value);

$page->fill(array(
	'foo' => 'bar',     // $page->fillFoo('bar');
	'e' => 'mc^2',      // $page->fillE('mc^2');
));