You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
842 lines
23 KiB
842 lines
23 KiB
1 year ago
|
<?php
|
||
|
/*
|
||
|
** Zabbix
|
||
|
** Copyright (C) 2001-2023 Zabbix SIA
|
||
|
**
|
||
|
** This program is free software; you can redistribute it and/or modify
|
||
|
** it under the terms of the GNU General Public License as published by
|
||
|
** the Free Software Foundation; either version 2 of the License, or
|
||
|
** (at your option) any later version.
|
||
|
**
|
||
|
** This program is distributed in the hope that it will be useful,
|
||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
** GNU General Public License for more details.
|
||
|
**
|
||
|
** You should have received a copy of the GNU General Public License
|
||
|
** along with this program; if not, write to the Free Software
|
||
|
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
**/
|
||
|
|
||
|
|
||
|
require_once dirname(__FILE__).'/../../include/CWebTest.php';
|
||
|
require_once dirname(__FILE__).'/../../include/helpers/CDataHelper.php';
|
||
|
require_once dirname(__FILE__).'/../traits/TableTrait.php';
|
||
|
|
||
|
/**
|
||
|
* @backup history_uint, profiles
|
||
|
*
|
||
|
* @onBefore prepareItemTagsData
|
||
|
*/
|
||
|
class testPageMonitoringLatestData extends CWebTest {
|
||
|
|
||
|
use TableTrait;
|
||
|
|
||
|
private function getTableSelector() {
|
||
|
return 'xpath://table['.CXPathHelper::fromClass('overflow-ellipsis').']';
|
||
|
}
|
||
|
|
||
|
private function getTable() {
|
||
|
return $this->query($this->getTableSelector())->asTable()->one();
|
||
|
}
|
||
|
|
||
|
const HOSTNAME = 'Host for items tags filtering';
|
||
|
|
||
|
// Host with items for filtering Latest data by item tags.
|
||
|
protected static $data = [
|
||
|
'hostgroupid' => null,
|
||
|
'hostid' => null,
|
||
|
'itemids' => [
|
||
|
'tag_item_1',
|
||
|
'tag_item_2',
|
||
|
'tag_item_3',
|
||
|
'tag_item_4'
|
||
|
]
|
||
|
];
|
||
|
|
||
|
public function prepareItemTagsData() {
|
||
|
// Create hostgroup for host with items and tags.
|
||
|
$hostgroups = CDataHelper::call('hostgroup.create', [['name' => 'Group for Items With tags']]);
|
||
|
$this->assertArrayHasKey('groupids', $hostgroups);
|
||
|
self::$data['hostgroupid'] = $hostgroups['groupids'][0];
|
||
|
|
||
|
// Create host for items.
|
||
|
$hosts = CDataHelper::call('host.create', [
|
||
|
'host' => self::HOSTNAME,
|
||
|
'groups' => [['groupid' => self::$data['hostgroupid']]]
|
||
|
]);
|
||
|
$this->assertArrayHasKey('hostids', $hosts);
|
||
|
|
||
|
$hostids = CDataHelper::getIds('host');
|
||
|
self::$data['hostid'] = $hostids['Host for items tags filtering'];
|
||
|
|
||
|
// Create items on previously created host.
|
||
|
$items_tags_data = [];
|
||
|
foreach (self::$data['itemids'] as $i => $item) {
|
||
|
$items_tags_data[] = [
|
||
|
'hostid' => self::$data['hostid'],
|
||
|
'name' => $item,
|
||
|
'key_' => 'trapper'.$i,
|
||
|
'type' => 2,
|
||
|
'value_type' => 0,
|
||
|
'tags' => [
|
||
|
[
|
||
|
'tag' => 'tag',
|
||
|
'value' => 'filtering_value'
|
||
|
],
|
||
|
[
|
||
|
'tag' => 'tag_number',
|
||
|
'value' => strval($i)
|
||
|
],
|
||
|
[
|
||
|
'tag' => 'component',
|
||
|
'value' => 'name:'.$item
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
}
|
||
|
|
||
|
$items = CDataHelper::call('item.create', $items_tags_data);
|
||
|
|
||
|
self::$data['itemids']['tag_item_1'] = $items['itemids'][0];
|
||
|
self::$data['itemids']['tag_item_2'] = $items['itemids'][1];
|
||
|
self::$data['itemids']['tag_item_3'] = $items['itemids'][2];
|
||
|
self::$data['itemids']['tag_item_4'] = $items['itemids'][3];
|
||
|
|
||
|
// Add data to one item to see "With data"/"Without data" subfilter.
|
||
|
$time = time() - 100;
|
||
|
DBexecute("INSERT INTO history (itemid, clock, value, ns) VALUES (".zbx_dbstr(self::$data['itemids']['tag_item_1']).
|
||
|
", ".zbx_dbstr($time).", 1, 0)");
|
||
|
}
|
||
|
|
||
|
public function testPageMonitoringLatestData_CheckLayout() {
|
||
|
$this->page->login()->open('zabbix.php?action=latest.view&filter_reset=1')->waitUntilReady();
|
||
|
$this->page->assertTitle('Latest data');
|
||
|
$this->page->assertHeader('Latest data');
|
||
|
$form = $this->query('name:zbx_filter')->asForm()->one();
|
||
|
$this->assertEquals(['Host groups', 'Hosts', 'Name', 'Tags', 'Show tags', 'Tag display priority', 'State', 'Show details'],
|
||
|
$form->getLabels()->asText()
|
||
|
);
|
||
|
$this->assertTrue($this->query('button:Apply')->one()->isClickable());
|
||
|
|
||
|
$subfilter = $this->query('id:latest-data-subfilter')->asTable()->one();
|
||
|
$this->assertTrue($subfilter->query('xpath:.//h4[text()="Subfilter "]/span[@class="grey" and '.
|
||
|
'text()="affects only filtered data"]')->one()->isValid()
|
||
|
);
|
||
|
|
||
|
foreach (['Hosts', 'Tags', 'Tag values'] as $header) {
|
||
|
$this->assertTrue($subfilter->query("xpath:.//h3[text()=".CXPathHelper::escapeQuotes($header)."]")
|
||
|
->one()->isValid()
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// With data/Without data subfilter is always present.
|
||
|
$subfilter_queries = ['xpath:.//h3[text()="Data"]', 'link:With data', 'link:Without data'];
|
||
|
|
||
|
foreach ($subfilter_queries as $query) {
|
||
|
$this->assertTrue($subfilter->query($query)->one()->isValid());
|
||
|
}
|
||
|
|
||
|
$form->fill(['Hosts' => self::HOSTNAME]);
|
||
|
$form->submit();
|
||
|
$subfilter->waitUntilReloaded();
|
||
|
|
||
|
foreach ($subfilter_queries as $query) {
|
||
|
$this->assertTrue($subfilter->query($query)->one()->isValid());
|
||
|
}
|
||
|
|
||
|
$this->query('button:Reset')->waitUntilClickable()->one()->click();
|
||
|
$subfilter->waitUntilReloaded();
|
||
|
|
||
|
// Check table headers.
|
||
|
$details_headers = [
|
||
|
true => ['', 'Host', 'Name', 'Interval', 'History', 'Trends', 'Type', 'Last check', 'Last value',
|
||
|
'Change', 'Tags', '', 'Info'],
|
||
|
false => ['', 'Host', 'Name', 'Last check', 'Last value', 'Change', 'Tags', '', 'Info']
|
||
|
];
|
||
|
|
||
|
foreach ($details_headers as $status => $headers) {
|
||
|
$this->query('name:show_details')->one()->asCheckbox()->set($status);
|
||
|
$form->submit();
|
||
|
$subfilter->waitUntilReloaded();
|
||
|
$this->assertEquals($headers, $this->getTable()->getHeadersText());
|
||
|
}
|
||
|
|
||
|
// Check that sortable headers are clickable.
|
||
|
foreach (['Host', 'Name'] as $header) {
|
||
|
$this->assertTrue($this->getTable()->query('xpath:.//th/a[text()="'.$header.'"]')->one()->isClickable());
|
||
|
}
|
||
|
|
||
|
// Check filter collapse/expand.
|
||
|
$filter_tab = $this->query('xpath://a[contains(@class, "tabfilter-item-link")]')->one();
|
||
|
foreach ([false, true] as $status) {
|
||
|
$this->assertEquals($status, $this->query('xpath://div[contains(@class, "tabfilter-collapsed")]')
|
||
|
->one(false)->isValid()
|
||
|
);
|
||
|
$filter_tab->click();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function getFilterData() {
|
||
|
return [
|
||
|
// Host groups and Show details.
|
||
|
[
|
||
|
[
|
||
|
'filter' => [
|
||
|
'Host groups' => 'Another group to check Overview',
|
||
|
'Show details' => true
|
||
|
],
|
||
|
'result' => [
|
||
|
[
|
||
|
'Name' => "4_item".
|
||
|
"\ntrap[4]"
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Hosts.
|
||
|
[
|
||
|
[
|
||
|
'filter' => [
|
||
|
'Hosts' => '1_Host_to_check_Monitoring_Overview'
|
||
|
],
|
||
|
'result' => [
|
||
|
['Name' => '1_item'],
|
||
|
['Name' => '2_item']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Name.
|
||
|
[
|
||
|
[
|
||
|
'filter' => [
|
||
|
'Name' => '3_item'
|
||
|
],
|
||
|
'result' => [
|
||
|
['Name' => '3_item']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Evaluation: And/Or, Operator Exists
|
||
|
[
|
||
|
[
|
||
|
'Tags' => [
|
||
|
'Evaluation' => 'And/Or',
|
||
|
'tags' => [
|
||
|
[
|
||
|
'index' => 0,
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'tag' => 'DataBase',
|
||
|
'operator' => 'Exists'
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
'result' => [
|
||
|
['Name' => '1_item'],
|
||
|
['Name' => '2_item'],
|
||
|
['Name' => '3_item'],
|
||
|
['Name' => '4_item']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Evaluation: Or, Operators: Equals, Contains.
|
||
|
[
|
||
|
[
|
||
|
'Tags' => [
|
||
|
'Evaluation' => 'Or',
|
||
|
'tags' => [
|
||
|
[
|
||
|
'index' => 0,
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'tag' => 'tag_number',
|
||
|
'operator' => 'Contains',
|
||
|
'value' => '0'
|
||
|
],
|
||
|
[
|
||
|
'tag' => 'DataBase',
|
||
|
'operator' => 'Equals',
|
||
|
'value' => 'mysql'
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
'result' => [
|
||
|
['Name' => '1_item'],
|
||
|
['Name' => 'tag_item_1']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// The same tags as previous case, but Evaluation: And. Result: Empty table.
|
||
|
[
|
||
|
[
|
||
|
'Tags' => [
|
||
|
'Evaluation' => 'And/Or',
|
||
|
'tags' => [
|
||
|
[
|
||
|
'index' => 0,
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'tag' => 'tag_number',
|
||
|
'operator' => 'Contains',
|
||
|
'value' => '0'
|
||
|
],
|
||
|
[
|
||
|
'tag' => 'DataBase',
|
||
|
'operator' => 'Equals',
|
||
|
'value' => 'mysql'
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
'result' => []
|
||
|
]
|
||
|
],
|
||
|
// Operators: Does not contain, Does not equal, Exists.
|
||
|
[
|
||
|
[
|
||
|
'Tags' => [
|
||
|
'evaluation_type' => 'And/Or',
|
||
|
'tags' => [
|
||
|
[
|
||
|
'index' => 0,
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'tag' => 'tag_number',
|
||
|
'operator' => 'Does not equal',
|
||
|
'value' => '1'
|
||
|
],
|
||
|
[
|
||
|
'tag' => 'component',
|
||
|
'operator' => 'Does not contain',
|
||
|
'value' => '1'
|
||
|
],
|
||
|
[
|
||
|
'tag' => 'tag',
|
||
|
'operator' => 'Exists'
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
'result' => [
|
||
|
['Name' => 'tag_item_3'],
|
||
|
['Name' => 'tag_item_4']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Operator: Does not exist and Exists.
|
||
|
[
|
||
|
[
|
||
|
'Tags' => [
|
||
|
'evaluation_type' => 'And/Or',
|
||
|
'tags' => [
|
||
|
[
|
||
|
'index' => 0,
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'tag' => 'tag',
|
||
|
'operator' => 'Exists'
|
||
|
],
|
||
|
[
|
||
|
'tag' => 'DataBase',
|
||
|
'operator' => 'Does not exist'
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
'result' => [
|
||
|
['Name' => 'tag_item_1'],
|
||
|
['Name' => 'tag_item_2'],
|
||
|
['Name' => 'tag_item_3'],
|
||
|
['Name' => 'tag_item_4']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Tags None.
|
||
|
[
|
||
|
[
|
||
|
'filter' => [
|
||
|
'Name' => 'tag_item_1'
|
||
|
],
|
||
|
'Show tags' => 'None',
|
||
|
'result' => [
|
||
|
['Name' => 'tag_item_1']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Tags: 1.
|
||
|
[
|
||
|
[
|
||
|
'filter' => [
|
||
|
'Name' => 'tag_item_1'
|
||
|
],
|
||
|
'Show tags' => '1',
|
||
|
'result' => [
|
||
|
['Name' => 'tag_item_1', 'Tags' => 'component: name:tag_item_1']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Tags: 2.
|
||
|
[
|
||
|
[
|
||
|
'filter' => [
|
||
|
'Name' => 'tag_item_1'
|
||
|
],
|
||
|
'Show tags' => '2',
|
||
|
'result' => [
|
||
|
['Name' => 'tag_item_1', 'Tags' => 'component: name:tag_item_1tag: filtering_value']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Tags: 3. Tag name: Full.
|
||
|
[
|
||
|
[
|
||
|
'filter' => [
|
||
|
'Name' => 'tag_item_1'
|
||
|
],
|
||
|
'Show tags' => '3',
|
||
|
'Tags name' => 'Full',
|
||
|
'result' => [
|
||
|
['Name' => 'tag_item_1', 'Tags' => 'component: name:tag_item_1tag: filtering_valuetag_number: 0']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Tag name: Shortened.
|
||
|
[
|
||
|
[
|
||
|
'filter' => [
|
||
|
'Name' => 'tag_item_1'
|
||
|
],
|
||
|
'Tags name' => 'Shortened',
|
||
|
'result' => [
|
||
|
['Name' => 'tag_item_1', 'Tags' => 'com: name:tag_item_1tag: filtering_valuetag: 0']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Tag name: None.
|
||
|
[
|
||
|
[
|
||
|
'filter' => [
|
||
|
'Name' => 'tag_item_1'
|
||
|
],
|
||
|
'Tags name' => 'None',
|
||
|
'result' => [
|
||
|
['Name' => 'tag_item_1', 'Tags' => 'name:tag_item_1filtering_value0']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Tag priority: no such tags.
|
||
|
[
|
||
|
[
|
||
|
'filter' => [
|
||
|
'Name' => 'tag_item_1',
|
||
|
'Tag display priority' => 'tag_'
|
||
|
],
|
||
|
'result' => [
|
||
|
['Name' => 'tag_item_1', 'Tags' => 'component: name:tag_item_1tag: filtering_valuetag_number: 0']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Tag priority: opposite alphabetic.
|
||
|
[
|
||
|
[
|
||
|
'filter' => [
|
||
|
'Name' => 'tag_item_1',
|
||
|
'Tag display priority' => 'tag_number,tag,component'
|
||
|
],
|
||
|
'result' => [
|
||
|
['Name' => 'tag_item_1', 'Tags' => 'tag_number: 0tag: filtering_valuecomponent: name:tag_item_1']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Tag priority: one first.
|
||
|
[
|
||
|
[
|
||
|
'filter' => [
|
||
|
'Name' => 'tag_item_1',
|
||
|
'Tag display priority' => 'tag'
|
||
|
],
|
||
|
'result' => [
|
||
|
['Name' => 'tag_item_1', 'Tags' => 'tag: filtering_valuecomponent: name:tag_item_1tag_number: 0']
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test for checking filtered results by values in main filter.
|
||
|
*
|
||
|
* @dataProvider getFilterData
|
||
|
*/
|
||
|
public function testPageMonitoringLatestData_Filter($data) {
|
||
|
$this->page->login()->open('zabbix.php?action=latest.view')->waitUntilReady();
|
||
|
$form = $this->query('name:zbx_filter')->waitUntilPresent()->asForm()->one();
|
||
|
$table = $this->query('xpath://table[contains(@class, "overflow-ellipsis")]')->asTable()->waitUntilPresent()->one();
|
||
|
|
||
|
// Reset filter in case if some filtering remained before ongoing test case.
|
||
|
$this->query('button:Reset')->one()->click();
|
||
|
$table->waitUntilReloaded();
|
||
|
|
||
|
// Fill filter form with data.
|
||
|
$form->fill(CTestArrayHelper::get($data, 'filter'));
|
||
|
|
||
|
// If data contains Tags and their settings, fill them separataly, because tags form is more complicated.
|
||
|
if (CTestArrayHelper::get($data, 'Tags')) {
|
||
|
$form->getField('id:evaltype_0')->asSegmentedRadio()->fill(CTestArrayHelper::get($data, 'Tags.Evaluation', 'And/Or'));
|
||
|
$form->getField('id:tags_0')->asMultifieldTable()->fill(CTestArrayHelper::get($data, 'Tags.tags', []));
|
||
|
}
|
||
|
|
||
|
$form->getField('id:show_tags_0')->asSegmentedRadio()->fill(CTestArrayHelper::get($data, 'Show tags', '3'));
|
||
|
$form->getField('id:tag_name_format_0')->asSegmentedRadio()->fill(CTestArrayHelper::get($data, 'Tags name', 'Full'));
|
||
|
|
||
|
$form->submit();
|
||
|
$table->waitUntilReloaded();
|
||
|
|
||
|
// Check filtered result.
|
||
|
$this->assertTableData($data['result'], $this->getTableSelector());
|
||
|
|
||
|
// Check Show tags filter setting.
|
||
|
if (CTestArrayHelper::get($data, 'Show tags') === 'None') {
|
||
|
$this->assertEquals(['', 'Host', 'Name', 'Last check', 'Last value', 'Change', '', 'Info'],
|
||
|
$this->getTable()->getHeadersText()
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// Reset filter not to impact the results of next tests.
|
||
|
$this->query('button:Reset')->one()->click();
|
||
|
$table->waitUntilReloaded();
|
||
|
}
|
||
|
|
||
|
public static function getSubfilterData() {
|
||
|
return [
|
||
|
// Tag values.
|
||
|
[
|
||
|
[
|
||
|
'subfilter' => [
|
||
|
'Tag values' => [
|
||
|
'name:tag_item_1',
|
||
|
'name:tag_item_2'
|
||
|
]
|
||
|
],
|
||
|
'result' => [
|
||
|
['Name' => 'tag_item_1'],
|
||
|
['Name' => 'tag_item_2']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Tag values and Data.
|
||
|
[
|
||
|
[
|
||
|
'subfilter' => [
|
||
|
'Tag values' => [
|
||
|
'name:tag_item_1',
|
||
|
'name:tag_item_2'
|
||
|
],
|
||
|
'Data' => [
|
||
|
'With data'
|
||
|
]
|
||
|
],
|
||
|
'result' => [
|
||
|
['Name' => 'tag_item_1']
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Hosts and Tag values.
|
||
|
[
|
||
|
[
|
||
|
'subfilter' => [
|
||
|
'Hosts' => [
|
||
|
'1_Host_to_check_Monitoring_Overview',
|
||
|
'3_Host_to_check_Monitoring_Overview'
|
||
|
],
|
||
|
'Tag values' => [
|
||
|
'Oracle'
|
||
|
]
|
||
|
],
|
||
|
'result' => [
|
||
|
['Name' => '3_item']
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test for checking filtered results clicking on subfilter.
|
||
|
*
|
||
|
* @dataProvider getSubfilterData
|
||
|
*/
|
||
|
public function testPageMonitoringLatestData_Subfilter($data) {
|
||
|
$hostid = CDBHelper::getValue('SELECT hostid FROM hosts WHERE name='.zbx_dbstr(self::HOSTNAME));
|
||
|
|
||
|
$link = (CTestArrayHelper::get($data['subfilter'], 'Data'))
|
||
|
? 'zabbix.php?action=latest.view&hostids%5B%5D='.$hostid
|
||
|
: 'zabbix.php?action=latest.view';
|
||
|
|
||
|
$this->page->login()->open($link)->waitUntilReady();
|
||
|
|
||
|
foreach ($data['subfilter'] as $header => $values) {
|
||
|
foreach ($values as $value) {
|
||
|
$this->query("xpath://h3[text()=".CXPathHelper::escapeQuotes($header)."]/..//a[text()=".
|
||
|
CXPathHelper::escapeQuotes($value)."]")->waitUntilClickable()->one()->click();
|
||
|
$this->page->waitUntilReady();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check that page remained the same.
|
||
|
$this->page->assertTitle('Latest data');
|
||
|
$this->page->assertHeader('Latest data');
|
||
|
|
||
|
$this->assertTableData($data['result'], $this->getTableSelector());
|
||
|
$this->query('button:Reset')->waitUntilClickable()->one()->click();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test for clicking on particular item tag in table and checking that items are filtered by this tag.
|
||
|
*/
|
||
|
public function testPageMonitoringLatestData_ClickTag() {
|
||
|
$tag = ['tag' => 'component: ', 'value' => 'storage'];
|
||
|
|
||
|
$hostid = CDBHelper::getValue('SELECT hostid FROM hosts WHERE name='.zbx_dbstr('ЗАББИКС Сервер'));
|
||
|
$this->page->login()->open('zabbix.php?action=latest.view&hostids%5B%5D='.$hostid)->waitUntilReady();
|
||
|
|
||
|
$this->getTable()->query('button', $tag['tag'].$tag['value'])->waitUntilClickable()->one()->click();
|
||
|
$this->page->waitUntilReady();
|
||
|
|
||
|
// Check that page remained the same.
|
||
|
$this->page->assertTitle('Latest data');
|
||
|
$this->page->assertHeader('Latest data');
|
||
|
|
||
|
// Check that tag value is selected in subfilter under correct header.
|
||
|
$this->assertTrue($this->query("xpath://td/h3[text()='Tag values']/..//label[text()=".
|
||
|
CXPathHelper::escapeQuotes($tag['tag'])."]/../..//span[@class=".
|
||
|
CXPathHelper::fromClass('subfilter-enabled')."]/a[text()=".
|
||
|
CXPathHelper::escapeQuotes($tag['value'])."]")->exists()
|
||
|
);
|
||
|
|
||
|
$this->assertTableData([
|
||
|
['Name' => 'Linux: Free swap space'],
|
||
|
['Name' => 'Linux: Free swap space in %'],
|
||
|
['Name' => 'Linux: Total swap space']
|
||
|
], $this->getTableSelector()
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test that checks if host has visible name, it cannot be found by host name on Latest Data page.
|
||
|
*/
|
||
|
public function testPageMonitoringLatestData_NoHostNames() {
|
||
|
$result = [
|
||
|
CDBHelper::getRandom(
|
||
|
'SELECT host'.
|
||
|
' FROM hosts'.
|
||
|
' WHERE status IN ('.HOST_STATUS_MONITORED.')'.
|
||
|
' AND name <> host', 3
|
||
|
),
|
||
|
|
||
|
CDBHelper::getRandom(
|
||
|
'SELECT host'.
|
||
|
' FROM hosts'.
|
||
|
' WHERE status IN ('.HOST_STATUS_NOT_MONITORED.')'.
|
||
|
' AND name <> host', 3
|
||
|
),
|
||
|
|
||
|
CDBHelper::getRandom(
|
||
|
'SELECT host'.
|
||
|
' FROM hosts'.
|
||
|
' WHERE status IN ('.HOST_STATUS_TEMPLATE.')'.
|
||
|
' AND name <> host', 3
|
||
|
)
|
||
|
];
|
||
|
|
||
|
$this->page->login()->open('zabbix.php?action=latest.view');
|
||
|
$this->query('button:Reset')->waitUntilClickable()->one()->click();
|
||
|
|
||
|
foreach ($result as $hosts) {
|
||
|
foreach ($hosts as $host) {
|
||
|
/*
|
||
|
* Check if hostname is present on page, if not, go to next page.
|
||
|
* Now there are 3 pages for unfiltered Latest data.
|
||
|
*/
|
||
|
for ($i = 1; $i < 3; $i++) {
|
||
|
$this->assertFalse($this->query('link', $host['host'])->one(false)->isValid());
|
||
|
$this->query('class:arrow-right')->waitUntilClickable()->one()->click();
|
||
|
$this->page->waitUntilReady();
|
||
|
}
|
||
|
|
||
|
$this->query('button:Reset')->waitUntilClickable()->one()->click();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function getItemDescription() {
|
||
|
return [
|
||
|
// Item without description.
|
||
|
[
|
||
|
[
|
||
|
'hostid' => '15003',
|
||
|
'Item name' => 'item_testPageHistory_CheckLayout_Log'
|
||
|
]
|
||
|
],
|
||
|
// Item with plain text in the description.
|
||
|
[
|
||
|
[
|
||
|
'hostid' => '15003',
|
||
|
'Item name' => 'item_testPageHistory_CheckLayout_Log_2',
|
||
|
'description' => 'Non-clickable description'
|
||
|
]
|
||
|
],
|
||
|
// Item with only 1 url in description.
|
||
|
[
|
||
|
[
|
||
|
'hostid' => '15003',
|
||
|
'Item name' => 'item_testPageHistory_CheckLayout_Eventlog',
|
||
|
'description' => 'https://zabbix.com'
|
||
|
]
|
||
|
],
|
||
|
// Item with text and url in description.
|
||
|
[
|
||
|
[
|
||
|
'hostid' => '15003',
|
||
|
'Item name' => 'item_testPageHistory_CheckLayout_Eventlog_2',
|
||
|
'description' => 'The following url should be clickable: https://zabbix.com'
|
||
|
]
|
||
|
],
|
||
|
// Item with multiple urls in description.
|
||
|
[
|
||
|
[
|
||
|
'hostid' => '15003',
|
||
|
'Item name' => 'item_testPageHistory_CheckLayout_Character',
|
||
|
'description' => 'http://zabbix.com https://www.zabbix.com/career https://www.zabbix.com/contact'
|
||
|
]
|
||
|
],
|
||
|
// Item with text and 2 urls in description.
|
||
|
[
|
||
|
[
|
||
|
'hostid' => '15003',
|
||
|
'Item name' => 'item_testPageHistory_CheckLayout_Text',
|
||
|
'description' => 'These urls should be clickable: https://zabbix.com https://www.zabbix.com/career'
|
||
|
]
|
||
|
],
|
||
|
// Item with underscore in macros name and one non existing macros in description .
|
||
|
[
|
||
|
[
|
||
|
'hostid' => '50010',
|
||
|
'Item name' => 'Http agent item form',
|
||
|
'description' => 'Underscore {$NONEXISTING}'
|
||
|
]
|
||
|
],
|
||
|
// Item with 2 macros in description.
|
||
|
[
|
||
|
[
|
||
|
'hostid' => '50010',
|
||
|
'Item name' => 'Http agent item for update',
|
||
|
'description' => '127.0.0.1 Some text'
|
||
|
]
|
||
|
],
|
||
|
// Item with 2 macros and text in description.
|
||
|
[
|
||
|
[
|
||
|
'hostid' => '50010',
|
||
|
'Item name' => 'Http agent item for delete',
|
||
|
'description' => 'Some text and IP number 127.0.0.1'
|
||
|
]
|
||
|
],
|
||
|
// Item with macros inside curly brackets.
|
||
|
[
|
||
|
[
|
||
|
'hostid' => '50007',
|
||
|
'Item name' => 'Item-layout-test-002',
|
||
|
'description' => '{Some text}'
|
||
|
]
|
||
|
],
|
||
|
// Item with macros in description.
|
||
|
[
|
||
|
[
|
||
|
'hostid' => '99027',
|
||
|
'Item name' => 'Item to check graph',
|
||
|
'description' => 'Some text'
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dataProvider getItemDescription
|
||
|
*/
|
||
|
public function testPageMonitoringLatestData_checkItemDescription($data) {
|
||
|
// Open Latest data for host 'testPageHistory_CheckLayout'
|
||
|
$this->page->login()->open('zabbix.php?&action=latest.view&show_details=0&hostids%5B%5D='.$data['hostid'])
|
||
|
->waitUntilReady();
|
||
|
|
||
|
// Find rows from the data provider and click on the description icon if such should persist.
|
||
|
$row = $this->getTable()->findRow('Name', $data['Item name'], true);
|
||
|
|
||
|
if (CTestArrayHelper::get($data,'description', false)) {
|
||
|
$row->query('class:zi-alert-with-content')->one()->click()->waitUntilReady();
|
||
|
$overlay = $this->query('xpath://div[@class="overlay-dialogue"]')->one();
|
||
|
|
||
|
// Verify the real description with the expected one.
|
||
|
$this->assertEquals($data['description'], $overlay->getText());
|
||
|
|
||
|
// Get urls form description.
|
||
|
$urls = [];
|
||
|
preg_match_all('/https?:\/\/\S+/', $data['description'], $urls);
|
||
|
// Verify that each of the urls is clickable.
|
||
|
foreach ($urls[0] as $url) {
|
||
|
$this->assertTrue($overlay->query('xpath:./div/a[@href="'.$url.'"]')->one()->isClickable());
|
||
|
}
|
||
|
|
||
|
// Verify that the tool-tip can be closed.
|
||
|
$overlay->query('xpath:./button[@title="Close"]')->one()->click();
|
||
|
$this->assertFalse($overlay->isDisplayed());
|
||
|
}
|
||
|
// If the item has no description the description icon should not be there.
|
||
|
else {
|
||
|
$this->assertTrue($row->query('class:icon-description')->count() === 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Maintenance icon hintbox.
|
||
|
*/
|
||
|
public function testPageMonitoringLatestData_checkMaintenanceIcon() {
|
||
|
$this->page->login()->open('zabbix.php?action=latest.view')->waitUntilReady();
|
||
|
$form = $this->query('name:zbx_filter')->asForm()->one();
|
||
|
$form->fill(['Hosts' => 'Available host in maintenance']);
|
||
|
$form->submit();
|
||
|
|
||
|
$this->query('xpath://button['.CXPathHelper::fromClass('zi-wrench-alt-small').']')->waitUntilClickable()->one()->click();
|
||
|
$hint = $this->query('xpath://div[@data-hintboxid]')->asOverlayDialog()->waitUntilPresent()->all()->last()->getText();
|
||
|
$hint_text = "Maintenance for Host availability widget [Maintenance with data collection]\n".
|
||
|
"Maintenance for checking Show hosts in maintenance option in Host availability widget";
|
||
|
$this->assertEquals($hint_text, $hint);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check hint text for Last check and Last value columns
|
||
|
*/
|
||
|
public function testPageMonitoringLatestData_checkHints() {
|
||
|
$itemid = CDBHelper::getValue('SELECT itemid FROM items WHERE name='.zbx_dbstr('4_item'));
|
||
|
$time = time();
|
||
|
$value = '15';
|
||
|
$true_time = date("Y-m-d H:i:s", $time);
|
||
|
|
||
|
DBexecute('INSERT INTO history_uint (itemid, clock, value, ns) VALUES ('.zbx_dbstr($itemid).
|
||
|
', '.zbx_dbstr($time).', '.zbx_dbstr($value).', 0)'
|
||
|
);
|
||
|
|
||
|
$this->page->login()->open('zabbix.php?action=latest.view')->waitUntilReady();
|
||
|
$form = $this->query('name:zbx_filter')->asForm()->one();
|
||
|
$table = $this->query('xpath://table[contains(@class, "overflow-ellipsis")]')->asTable()->waitUntilPresent()->one();
|
||
|
$this->query('button:Reset')->one()->click();
|
||
|
$table->waitUntilReloaded();
|
||
|
$form->fill(['Name' => '4_item'])->submit();
|
||
|
$table->waitUntilReloaded();
|
||
|
|
||
|
foreach (['Last check', 'Last value'] as $column) {
|
||
|
if ($column === 'Last value') {
|
||
|
$this->assertEquals('15 UNIT', $this->getTable()->getRow(0)->getColumn($column)->getText());
|
||
|
}
|
||
|
|
||
|
$this->getTable()->getRow(0)->getColumn($column)->query('class:cursor-pointer')->one()->click();
|
||
|
$hint = $this->query('xpath://div[@data-hintboxid]')->asOverlayDialog()->waitUntilPresent()->all()->last()->getText();
|
||
|
$compare_hint = ($column === 'Last check') ? $true_time : $value;
|
||
|
$this->assertEquals($compare_hint, $hint);
|
||
|
}
|
||
|
}
|
||
|
}
|