Merge branch release/21.7.7 of zentao/zentaopms (#12157)
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
require_once dirname(__FILE__, 6) . '/test/lib/ui.php';
|
||||
|
||||
define('EXECUTION_COLUMNS', array('id', 'name', 'status', 'role', 'begin', 'end', 'join', 'hours'));
|
||||
define('PAGESIZE', array(5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 100, 200, 500, 1000, 2000));
|
||||
|
||||
class executionTester extends tester
|
||||
{
|
||||
/**
|
||||
* 校验user模块execution视图的内容及分页功能
|
||||
* Verify the content and pagination of user execution view.
|
||||
*
|
||||
* @param array $users 用户列表
|
||||
* @param array $executions execution数据
|
||||
* @param int $pageSize 每页大小
|
||||
* @return object 成功或失败对象
|
||||
*/
|
||||
public function verifyUserExecutionContentAndPagination($users = array(), $executions = array(), $pageSize = 5)
|
||||
{
|
||||
if(empty($users)) return $this->failed('用户列表不能为空');
|
||||
if(empty($executions)) return $this->failed('execution数据不能为空');
|
||||
if(!in_array($pageSize, PAGESIZE, true)) return $this->failed('pageSize无效');
|
||||
|
||||
$this->login();
|
||||
$form = $this->initForm('user', 'execution', array('userID' => $users[0]->id), 'appIframe-system');
|
||||
$form->wait(2);
|
||||
|
||||
foreach($users as $user)
|
||||
{
|
||||
if($user != $users[0])
|
||||
{
|
||||
$form->dom->userPicker->picker($user->realname);
|
||||
$form->wait(2);
|
||||
if($form->dom->userPicker->getText() != $user->realname) return $this->failed('execution页面切换用户显示失败');
|
||||
}
|
||||
|
||||
$userExecutions = isset($executions[$user->account]) ? $executions[$user->account] : array();
|
||||
|
||||
$ret = $this->verifyContent($form, $user, $userExecutions);
|
||||
if($ret) return $ret;
|
||||
|
||||
$items = $form->dom->getElementListByXpathKey('id');
|
||||
$ret = $this->verifyPagination($form, $items, $pageSize);
|
||||
if($ret) return $ret;
|
||||
}
|
||||
|
||||
return $this->success("开源版m=user&f=execution测试成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证内容
|
||||
* verify content
|
||||
*
|
||||
* @param object $form 页面对象
|
||||
* @param object $user 用户对象
|
||||
* @param array $executions 过滤后的execution数据
|
||||
* @return object 成功返回null,失败返回对象
|
||||
*/
|
||||
private function verifyContent($form, $user, $executions)
|
||||
{
|
||||
$currentPageSize = (int) filter_var($form->dom->pagerSizeMenu->getText(), FILTER_SANITIZE_NUMBER_INT);
|
||||
|
||||
if(count($executions) > $currentPageSize)
|
||||
{
|
||||
$form->dom->pagerSizeMenu->click();
|
||||
$form->wait(1);
|
||||
$form->dom->dropdownPicker(max(PAGESIZE));
|
||||
$form->wait(1);
|
||||
}
|
||||
|
||||
$display = array();
|
||||
foreach(EXECUTION_COLUMNS as $c) $display[$c] = $form->dom->getElementListByXpathKey($c, true);
|
||||
|
||||
if(count($display['id']) != count($executions)) return $this->failed("用户'{$user->realname}'的执行数量不符: 期望" . count($executions) . "条,实际" . count($display['id']) . "条");
|
||||
|
||||
foreach($display['id'] as $i => $idText)
|
||||
{
|
||||
$id = (int)trim($idText);
|
||||
if(!isset($executions[$id])) return $this->failed("用户'{$user->realname}'执行页面显示了不应该显示的ID: {$id}");
|
||||
$execution = $executions[$id];
|
||||
foreach(EXECUTION_COLUMNS as $column)
|
||||
{
|
||||
$displayValue = $display[$column][$i] ?? '';
|
||||
if($column == 'status') $expected = $this->lang->program->statusList->{$execution->status} ?? $execution->status;
|
||||
else $expected = $execution->{$column} ?? '';
|
||||
if($displayValue != $expected) return $this->failed("用户'{$user->realname}'执行页面ID={$id} {$column}不匹配,期望'{$expected}',实际'{$displayValue}'");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证分页
|
||||
* verify pagination
|
||||
*
|
||||
* @param object $form 页面对象
|
||||
* @param array $items 需求数据
|
||||
* @param int $pageSize 每页数量
|
||||
* @return object 成功返回null,失败返回对象
|
||||
*/
|
||||
private function verifyPagination($form, $items, $pageSize = 5)
|
||||
{
|
||||
$totalTasks = count($items);
|
||||
$pages = (int) ceil($totalTasks / $pageSize);
|
||||
|
||||
if(count($items) > $pageSize)
|
||||
{
|
||||
$form->dom->pagerSizeMenu->click();
|
||||
$form->wait(1);
|
||||
$form->dom->dropdownPicker($pageSize);
|
||||
$form->dom->firstPage->click();
|
||||
$form->wait(1);
|
||||
}
|
||||
|
||||
for($i = 1; $i <= $pages; $i++)
|
||||
{
|
||||
$totalActual = count($form->dom->getElementListByXpathKey('id' ));
|
||||
$totalExpected = ($pages === 1) ? $totalTasks : ($i < $pages ? $pageSize : ($totalTasks - $pageSize * ($pages - 1)));
|
||||
|
||||
if($totalActual !== $totalExpected) return $this->failed("分页第{$i}页数量不匹配:期望{$totalExpected},实际{$totalActual}");
|
||||
|
||||
if($i < $pages && $form->dom->nextPage)
|
||||
{
|
||||
$form->dom->nextPage->click();
|
||||
$form->wait(1);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Executable
+93
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(__FILE__, 2) . '/lib/ui/execution.ui.class.php';
|
||||
|
||||
/**
|
||||
|
||||
title=开源版m=user&f=execution测试
|
||||
timeout=0
|
||||
cid=1
|
||||
|
||||
- 开源版m=user&f=execution测试
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @开源版m=user&f=execution测试成功
|
||||
|
||||
*/
|
||||
|
||||
$user = zenData('user');
|
||||
$user->id->range('1-3');
|
||||
$user->account->range('admin,user1,user2');
|
||||
$user->realname->range('管理员,用户1,用户2');
|
||||
$user->password->range($config->uitest->defaultPassword)->format('md5');
|
||||
$user->role->range('admin,dev,qa');
|
||||
$user->gender->range('f,m');
|
||||
$user->gen(3);
|
||||
|
||||
$product = zenData('product');
|
||||
$product->id->range('1');
|
||||
$product->name->range('产品1');
|
||||
$product->type->range('normal');
|
||||
$product->status->range('normal');
|
||||
$product->gen(1);
|
||||
|
||||
$project = zenData('project');
|
||||
$project->id->range('1-2');
|
||||
$project->name->range('项目1,项目2');
|
||||
$project->model->range('scrum');
|
||||
$project->status->range('doing');
|
||||
$project->type->range('project');
|
||||
$project->gen(2);
|
||||
|
||||
$execution = zenData('project');
|
||||
$execution->id->range('101-106');
|
||||
$execution->project->range('1{3},2{3}');
|
||||
$execution->type->range('sprint');
|
||||
$execution->name->range('101-106')->prefix('执行');
|
||||
$execution->status->range('wait,doing,suspended,closed');
|
||||
$execution->deleted->range('0');
|
||||
$execution->multiple->range('1');
|
||||
$execution->vision->range('rnd');
|
||||
$execution->gen(6, false);
|
||||
|
||||
$team = zenData('team');
|
||||
$team->id->range('1-18');
|
||||
$team->root->range('101-106{3}');
|
||||
$team->type->range('execution');
|
||||
$team->account->range('admin,user1,user2');
|
||||
$team->role->range('项目经理,开发,测试');
|
||||
$team->join->range('`2023-01-01`,`2023-01-15`,`2023-02-01`');
|
||||
$team->hours->range('8,6,4');
|
||||
$team->gen(18);
|
||||
|
||||
$task = zenData('task');
|
||||
$task->id->range('1-18');
|
||||
$task->execution->range('101-106{3}');
|
||||
$task->name->range('1-18')->prefix('任务');
|
||||
$task->assignedTo->range('admin{6},user1{6},user2{6}');
|
||||
$task->status->range('wait,doing,done');
|
||||
$task->deleted->range('0');
|
||||
$task->gen(18);
|
||||
|
||||
global $uiTester;
|
||||
$users = $uiTester->dao->select('*')->from('zt_user')->fetchAll();
|
||||
|
||||
// 按用户保存execution数据,包含team信息
|
||||
$executions = array();
|
||||
foreach($users as $user)
|
||||
{
|
||||
$userExecutions = $uiTester->dao->select("e.*, t.account, t.role, t.join, t.hours")
|
||||
->from('zt_project')->alias('e')
|
||||
->leftJoin('zt_team')->alias('t')->on('e.id = t.root AND t.type = "execution"')
|
||||
->where('e.type')->eq('sprint')
|
||||
->andWhere('e.deleted')->eq('0')
|
||||
->andWhere('t.account')->eq($user->account)
|
||||
->fetchAll('id');
|
||||
|
||||
$executions[$user->account] = $userExecutions;
|
||||
}
|
||||
|
||||
$tester = new executionTester();
|
||||
|
||||
r($tester->verifyUserExecutionContentAndPagination($users, $executions, 5)) && p('status,message') && e('SUCCESS,开源版m=user&f=execution测试成功'); //开源版m=user&f=execution测试
|
||||
|
||||
$tester->closeBrowser();
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
class executionPage extends page
|
||||
{
|
||||
public function __construct($webdriver)
|
||||
{
|
||||
parent::__construct($webdriver);
|
||||
|
||||
$this->xpath = array(
|
||||
// 顶部用户选择器
|
||||
'userPicker' => '//div[contains(@class, "picker-select-single")]',
|
||||
|
||||
// 列选择器(与 dtable 的 data-col 对齐)
|
||||
'id' => "//div[@data-col='id' and @data-row!='HEADER']",
|
||||
'name' => "//div[@data-col='name' and @data-row!='HEADER']",
|
||||
'status' => "//div[@data-col='status' and @data-row!='HEADER']",
|
||||
'role' => "//div[@data-col='role' and @data-row!='HEADER']",
|
||||
'begin' => "//div[@data-col='begin' and @data-row!='HEADER']",
|
||||
'end' => "//div[@data-col='end' and @data-row!='HEADER']",
|
||||
'join' => "//div[@data-col='join' and @data-row!='HEADER']",
|
||||
'hours' => "//div[@data-col='hours' and @data-row!='HEADER']",
|
||||
|
||||
// 分页控件(table id 按模块约定)
|
||||
'pagerSizeMenu' => "//button[contains(@class, 'pager-size-menu')]",
|
||||
'sizePerPage' => "//*[@class='menu-wrapper popup search-menu is-contextmenu']",
|
||||
'firstPage' => "//*[@id='table-user-execution']/div[3]/nav/a[1]",
|
||||
'prevPage' => "//*[@id='table-user-execution']/div[3]/nav/a[2]",
|
||||
'nextPage' => "//*[@id='table-user-execution']/div[3]/nav/a[3]",
|
||||
'lastPage' => "//*[@id='table-user-execution']/div[3]/nav/a[4]"
|
||||
);
|
||||
|
||||
$this->dom->xpath = array_merge($this->dom->xpath, $this->xpath);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user