<?php /* ** Copyright (C) 2001-2025 Zabbix SIA ** ** This program is free software: you can redistribute it and/or modify it under the terms of ** the GNU Affero General Public License as published by the Free Software Foundation, version 3. ** ** 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 Affero General Public License for more details. ** ** You should have received a copy of the GNU Affero General Public License along with this program. ** If not, see <https://www.gnu.org/licenses/>. **/ require_once dirname(__FILE__).'/../../include/CWebTest.php'; /** * @dataSource AllItemValueTypes * * @backup dashboard * * @onBefore prepareData */ class testDashboardItemNavigatorWidget extends testWidgets { /** * Attach MessageBehavior, TableBehavior and TagBehavior to the test. */ public function getBehaviors() { return [ CMessageBehavior::class, CTableBehavior::class, CTagBehavior::class ]; } protected static $dashboardid; protected static $groupids; protected static $update_widget = 'Update Item navigator widget'; const DEFAULT_WIDGET = 'Default Item navigator widget'; const DELETE_WIDGET = 'Widget for delete'; const DEFAULT_DASHBOARD = 'Dashboard for Item navigator widget test'; const DASHBOARD_FOR_WIDGET_CREATE = 'Dashboard for Item navigator widget create/update test'; /** * Get 'Group by' table element with mapping set. * * @return CMultifieldTable */ protected function getGroupByTable() { return $this->query('id:group_by-table')->asMultifieldTable([ 'mapping' => [ '2' => [ 'name' => 'attribute', 'selector' => 'xpath:./z-select', 'class' => 'CDropdownElement' ], '3' => [ 'name' => 'tag', 'selector' => 'xpath:./input', 'class' => 'CElement' ] ] ])->waitUntilVisible()->one(); } public static function prepareData() { CDataHelper::call('dashboard.create', [ [ 'name' => self::DEFAULT_DASHBOARD, 'pages' => [ [ 'name' => 'Page with default widgets', 'widgets' => [ [ 'type' => 'itemnavigator', 'name' => self::DEFAULT_WIDGET, 'x' => 0, 'y' => 0, 'width' => 36, 'height' => 5 ], [ 'type' => 'itemnavigator', 'name' => self::DELETE_WIDGET, 'x' => 36, 'y' => 0, 'width' => 36, 'height' => 5 ] ] ] ] ], [ 'name' => self::DASHBOARD_FOR_WIDGET_CREATE, 'pages' => [ [ 'name' => 'Page with created/updated widgets', 'widgets' => [ [ 'type' => 'itemnavigator', 'name' => self::$update_widget, 'x' => 0, 'y' => 0, 'width' => 36, 'height' => 5, 'fields' => [ [ 'type' => ZBX_WIDGET_FIELD_TYPE_STR, 'name' => 'reference', 'value' => 'ZBXIN' ] ] ] ] ] ] ] ]); self::$dashboardid = CDataHelper::getIds('name'); // Create hostgroups for hosts. CDataHelper::call('hostgroup.create', [ ['name' => 'First Group for Item navigator check'], ['name' => 'Second Group for Item navigator check'] ]); self::$groupids = CDataHelper::getIds('name'); // Create hosts. CDataHelper::createHosts([ [ 'host' => 'First host for Item navigator widget', 'interfaces' => [ [ 'type' => INTERFACE_TYPE_AGENT, 'main' => INTERFACE_PRIMARY, 'useip' => INTERFACE_USE_IP, 'ip' => '127.0.7.1', 'dns' => '', 'port' => '11197' ] ], 'groups' => [ 'groupid' => self::$groupids['First Group for Item navigator check'] ] ], [ 'host' => 'Second host for Item navigator widget', 'interfaces' => [ [ 'type' => INTERFACE_TYPE_AGENT, 'main' => INTERFACE_PRIMARY, 'useip' => INTERFACE_USE_IP, 'ip' => '127.0.7.2', 'dns' => '', 'port' => '11198' ] ], 'groups' => [ 'groupid' => self::$groupids['Second Group for Item navigator check'] ] ] ]); } public function testDashboardItemNavigatorWidget_Layout() { $this->page->login()->open('zabbix.php?action=dashboard.view&dashboardid='. self::$dashboardid[self::DEFAULT_DASHBOARD])->waitUntilReady(); $dashboard = CDashboardElement::find()->one(); $dialog = $dashboard->edit()->addWidget(); $this->assertEquals('Add widget', $dialog->getTitle()); $form = $dialog->asForm(); $form->fill(['Type' => CFormElement::RELOADABLE_FILL('Item navigator')]); // Check default state. $default_state = [ 'Type' => 'Item navigator', 'Name' => '', 'Show header' => true, 'Refresh interval' => 'Default (1 minute)', 'Host groups' => '', 'Hosts' => '', 'Host tags' => 'And/Or', 'id:host_tags_0_tag' => '', 'id:host_tags_0_operator' => 'Contains', 'id:host_tags_0_value' => '', 'Item patterns' => '', 'Item tags' => 'And/Or', 'id:item_tags_0_tag' => '', 'id:item_tags_0_operator' => 'Contains', 'id:item_tags_0_value' => '', 'State' => 'All', 'Show problems' => 'Unsuppressed', 'Group by' => [], 'Item limit' => 100 ]; $form->checkValue($default_state); $this->assertEquals(['Item limit'], $form->getRequiredLabels()); // Check dropdown options. $this->getGroupByTable()->fill(['attribute' => 'Host group']); $options = [ 'Refresh interval' => ['Default (1 minute)', 'No refresh', '10 seconds', '30 seconds', '1 minute', '2 minutes', '10 minutes', '15 minutes' ], 'id:host_tags_0_operator' => ['Exists', 'Equals', 'Contains', 'Does not exist', 'Does not equal', 'Does not contain' ], 'id:item_tags_0_operator' => ['Exists', 'Equals', 'Contains', 'Does not exist', 'Does not equal', 'Does not contain' ], 'Group by' => ['Host group', 'Host name', 'Host tag value', 'Item tag value'] ]; foreach ($options as $field => $values) { $this->assertEquals($values, $form->getField($field)->asDropdown()->getOptions()->asText()); } $inputs = [ 'Name' => [ 'maxlength' => 255, 'placeholder' => 'default' ], 'id:groupids__ms' => [ 'placeholder' => 'type here to search' ], 'id:hostids__ms' => [ 'placeholder' => 'type here to search' ], 'id:host_tags_0_tag' => [ 'maxlength' => 255, 'placeholder' => 'tag' ], 'id:host_tags_0_value' => [ 'maxlength' => 255, 'placeholder' => 'value' ], 'id:items__ms' => [ 'placeholder' => 'patterns' ], 'id:item_tags_0_tag' => [ 'maxlength' => 255, 'placeholder' => 'tag' ], 'id:item_tags_0_value' => [ 'maxlength' => 255, 'placeholder' => 'value' ], 'id:group_by_0_tag_name' => [ 'maxlength' => 255, 'placeholder' => 'tag' ], 'Item limit' => [ 'maxlength' => 4 ] ]; foreach ($inputs as $field => $attributes) { foreach ($attributes as $attribute => $value) { $this->assertEquals($value, $form->getField($field)->getAttribute($attribute)); } } // Check radio buttons. $selection_elements = [ 'Host tags' => ['And/Or', 'Or'], 'Item tags' => ['And/Or', 'Or'], 'State' => ['All', 'Normal', 'Not supported'], 'Show problems' => ['All', 'Unsuppressed', 'None'] ]; foreach ($selection_elements as $name => $labels) { $this->assertEquals($labels, $form->getField($name)->getLabels()->asText()); } // Check 'Host tags', 'Item tags' and 'Group by' table buttons. foreach (['id:tags_table_host_tags', 'id:tags_table_item_tags', 'id:group_by-table'] as $locator) { $this->assertEquals(2, $form->query($locator)->one()->query('button', ['Add', 'Remove'])->all() ->filter((CElementFilter::CLICKABLE))->count() ); } // Check if footer buttons present and clickable. $this->assertEquals(['Add', 'Cancel'], $dialog->getFooter()->query('button')->all() ->filter(CElementFilter::CLICKABLE)->asText() ); // Check Hosts and Host groups popup menu options. foreach (['Hosts', 'Host groups'] as $label) { $selector = $form->getField($label); $popup_menu = $selector->query('xpath:.//button[contains(@class, "zi-chevron-down")]')->one(); foreach ([$selector->query('button:Select')->one(), $popup_menu] as $button) { $this->assertTrue($button->isClickable()); } $options = ($label === 'Hosts') ? ['Hosts', 'Widget', 'Dashboard'] : ['Host groups', 'Widget']; $this->assertEquals($options, $popup_menu->asPopupButton()->getMenu()->getItems()->asText()); foreach ($options as $title) { $popup_menu->asPopupButton()->getMenu()->select($title); if ($title === 'Dashboard') { $form->checkValue([$label => 'Dashboard']); $this->assertTrue($selector->query('xpath:.//span[@data-hintbox-contents="Dashboard is used as data source."]') ->one()->isVisible() ); } else { $dialogs = COverlayDialogElement::find()->all()->waitUntilReady(); $this->assertEquals($title, $dialogs->last()->getTitle()); $dialogs->last()->close(); } } } COverlayDialogElement::find()->one()->close(); } public static function getWidgetData() { return [ // #0. [ [ 'expected' => TEST_BAD, 'fields' => [ 'Item limit' => '' ], 'error' => 'Invalid parameter "Item limit": value must be one of 1-9999.' ] ], // #1. [ [ 'expected' => TEST_BAD, 'fields' => [ 'Item limit' => ' ' ], 'error' => 'Invalid parameter "Item limit": value must be one of 1-9999.' ] ], // #2. [ [ 'expected' => TEST_BAD, 'fields' => [ 'Item limit' => '0' ], 'error' => 'Invalid parameter "Item limit": value must be one of 1-9999.' ] ], // #3. [ [ 'expected' => TEST_BAD, 'fields' => [ 'Item limit' => 'test' ], 'error' => 'Invalid parameter "Item limit": value must be one of 1-9999.' ] ], // #4. [ [ 'expected' => TEST_BAD, 'fields' => [], 'group_by' => [ ['attribute' => 'Host group'], ['attribute' => 'Host group'] ], 'error' => 'Invalid parameter "Group by": rows must be unique.' ] ], // #5. [ [ 'expected' => TEST_BAD, 'fields' => [], 'group_by' => [ ['attribute' => 'Host name'], ['attribute' => 'Host name'] ], 'error' => 'Invalid parameter "Group by": rows must be unique.' ] ], // #6. [ [ 'expected' => TEST_BAD, 'fields' => [], 'group_by' => [ ['attribute' => 'Item tag value', 'tag' => 'windows'], ['attribute' => 'Item tag value', 'tag' => 'windows'] ], 'error' => 'Invalid parameter "Group by": rows must be unique.' ] ], // #7. [ [ 'expected' => TEST_BAD, 'fields' => [], 'group_by' => [ ['attribute' => 'Host tag value', 'tag' => 'server'], ['attribute' => 'Host tag value', 'tag' => 'server'] ], 'error' => 'Invalid parameter "Group by": rows must be unique.' ] ], // #8. [ [ 'expected' => TEST_BAD, 'fields' => [], 'group_by' => [ ['attribute' => 'Host group'], ['attribute' => 'Host name'], ['attribute' => 'Host group'] ], 'error' => 'Invalid parameter "Group by": rows must be unique.' ] ], // #9. [ [ 'expected' => TEST_BAD, 'fields' => [], 'group_by' => [ ['attribute' => 'Item tag value', 'tag' => 'memory'], ['attribute' => 'Item tag value', 'tag' => 'cpu'], ['attribute' => 'Item tag value', 'tag' => 'memory'] ], 'error' => 'Invalid parameter "Group by": rows must be unique.' ] ], // #10. [ [ 'expected' => TEST_BAD, 'fields' => [], 'group_by' => [ ['attribute' => 'Host tag value', 'tag' => 'server'], ['attribute' => 'Host tag value', 'tag' => 'cpu'], ['attribute' => 'Host tag value', 'tag' => 'server'] ], 'error' => 'Invalid parameter "Group by": rows must be unique.' ] ], // #11. [ [ 'expected' => TEST_BAD, 'fields' => [], 'group_by' => [ ['attribute' => 'Host name'], ['attribute' => 'Item tag value', 'tag' => 'memory'], ['attribute' => 'Host name'] ], 'error' => 'Invalid parameter "Group by": rows must be unique.' ] ], // #12. [ [ 'expected' => TEST_BAD, 'fields' => [], 'group_by' => [ ['attribute' => 'Host tag value'] ], 'error' => 'Invalid parameter "Group by": tag cannot be empty.' ] ], // #13. [ [ 'expected' => TEST_BAD, 'fields' => [], 'group_by' => [ ['attribute' => 'Item tag value'] ], 'error' => 'Invalid parameter "Group by": tag cannot be empty.' ] ], // #14. [ [ 'expected' => TEST_GOOD, 'fields' => [] ] ], // #15. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Show header' => false, 'Refresh interval' => 'No refresh' ] ] ], // #16. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Host groups' => 'First Group for Item navigator check', 'Refresh interval' => '10 seconds' ] ] ], // #17. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Host groups' => [ 'First Group for Item navigator check', 'Second Group for Item navigator check' ], 'Refresh interval' => '30 seconds' ] ] ], // #18. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Hosts' => [ 'First host for Item navigator widget', 'Second host for Item navigator widget' ], 'Refresh interval' => '1 minute' ] ] ], // #19. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Host tags' => 'Or', 'Refresh interval' => '2 minutes' ] ] ], // #20. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Item patterns' => 'available*', 'Refresh interval' => '10 minutes' ] ] ], // #21. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Item tags' => 'Or', 'Refresh interval' => '15 minutes' ] ] ], // #22. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Host tags' => 'And/Or', 'Item tags' => 'And/Or', 'Item limit' => '1', 'Refresh interval' => 'Default (1 minute)' ] ] ], // #23. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Item limit' => '9999' ] ] ], // #24. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Name' => 'State => Normal', 'State' => 'Normal' ] ] ], // #25. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Name' => 'State => Not supported', 'State' => 'Not supported' ] ] ], // #26. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Name' => 'Show problems => All', 'Show problems' => 'All' ] ] ], // #27. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Name' => 'Show problems => None', 'Show problems' => 'None' ] ] ], // #28. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Name' => 'Check all "Group by" attributes' ], 'group_by' => [ ['attribute' => 'Host tag value', 'tag' => STRING_255], ['attribute' => 'Item tag value', 'tag' => STRING_255], ['attribute' => 'Host name'], ['attribute' => 'Host group'] ] ] ], // #29. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Name' => STRING_255, 'Show header' => true, 'Host groups' => [ 'First Group for Item navigator check', 'Second Group for Item navigator check' ], 'Hosts' => [ 'First host for Item navigator widget', 'Second host for Item navigator widget' ], 'Host tags' => 'Or', 'Item patterns' => 'memory*', 'Item tags' => 'Or', 'State' => 'All', 'Show problems' => 'Unsuppressed', 'Item limit' => '111' ], 'tags' => [ 'host' => [ ['name' => STRING_255, 'operator' => 'Does not contain', 'value' => STRING_255] ], 'item' => [ ['name' => STRING_255, 'operator' => 'Does not equal', 'value' => STRING_255] ] ] ] ], // #30. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Name' => ' Test trailing spaces ', 'Item limit' => ' 1 ', 'Item tags' => 'And/Or' ], 'tags' => [ 'host' => [ ['name' => ' Host ', 'operator' => 'Does not equal', 'value' => ' test '] ], 'item' => [ ['name' => ' Item ', 'operator' => 'Does not contain', 'value' => ' test '] ] ], 'trim' => ['Name', 'Item limit', 'id:host_tags_0_tag', 'id:host_tags_0_value', 'id:item_tags_0_tag', 'id:item_tags_0_value'] ] ], // #31. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Name' => 'Empty tag and value' ], 'tags' => [ 'host' => [ ['name' => '', 'operator' => 'Contains', 'value' => ''] ], 'item' => [ ['name' => '', 'operator' => 'Contains', 'value' => ''] ] ] ] ], // #32. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Name' => 'Different types of macro in input fields {$A}' ], 'tags' => [ 'host' => [ ['name' => '{HOST.NAME}', 'operator' => 'Does not contain', 'value' => '{HOST.CONN}'] ], 'item' => [ ['name' => '{ITEM.NAME}', 'operator' => 'Does not contain', 'value' => '{ITEM.VALUE}'] ] ], 'group_by' => [ ['attribute' => 'Host tag value', 'tag' => '{HOST.NAME}'], ['attribute' => 'Item tag value', 'tag' => '{ITEM.NAME}'] ] ] ], // #33 Check that host and item tags table contains entries with UTF-8 4-byte characters, empty tag/value and all possible operators. [ [ 'expected' => TEST_GOOD, 'fields' => [ 'Name' => 'Check tags table' ], 'tags' => [ 'host' => [ ['name' => 'empty value', 'operator' => 'Equals', 'value' => ''], ['name' => '', 'operator' => 'Does not contain', 'value' => 'empty tag'], ['name' => 'Check host tag with operator - Equals ⚠️', 'operator' => 'Equals', 'value' => 'Warning ⚠️'], ['name' => 'Check host tag with operator - Exists', 'operator' => 'Exists'], ['name' => 'Check host tag with operator - Contains ❌', 'operator' => 'Contains', 'value' => 'tag value ❌'], ['name' => 'Check host tag with operator - Does not exist', 'operator' => 'Does not exist'], ['name' => 'Check host tag with operator - Does not equal', 'operator' => 'Does not equal', 'value' => 'Average'], ['name' => 'Check host tag with operator - Does not contain', 'operator' => 'Does not contain', 'value' => 'Disaster'] ], 'item' => [ ['name' => 'empty value', 'operator' => 'Equals', 'value' => ''], ['name' => '', 'operator' => 'Does not contain', 'value' => 'empty tag'], ['name' => 'Check item tag with operator - Equals 🌵', 'operator' => 'Equals', 'value' => 'Warning 🌵'], ['name' => 'Check item tag with operator - Exists', 'operator' => 'Exists'], ['name' => 'Check item tag with operator - Contains 🐙', 'operator' => 'Contains', 'value' => 'tag value 🐙'], ['name' => 'Check item tag with operator - Does not exist', 'operator' => 'Does not exist'], ['name' => 'Check item tag with operator - Does not equal', 'operator' => 'Does not equal', 'value' => 'Average'], ['name' => 'Check item tag with operator - Does not contain', 'operator' => 'Does not contain', 'value' => 'Disaster'] ] ] ] ] ]; } /** * @dataProvider getWidgetData */ public function testDashboardItemNavigatorWidget_Create($data) { $this->checkWidgetForm($data); } /** * @dataProvider getWidgetData */ public function testDashboardItemNavigatorWidget_Update($data) { $this->checkWidgetForm($data, true); } public function testDashboardItemNavigatorWidget_SimpleUpdate() { $old_hash = CDBHelper::getHash(self::SQL); $this->setWidgetConfiguration(self::$dashboardid[self::DASHBOARD_FOR_WIDGET_CREATE], self::$update_widget); CDashboardElement::find()->one()->save(); $this->page->waitUntilReady(); $this->assertMessage(TEST_GOOD, 'Dashboard updated'); $this->assertEquals($old_hash, CDBHelper::getHash(self::SQL)); } /** * Perform Item navigator widget creation or update and verify the result. * * @param boolean $update updating is performed */ protected function checkWidgetForm($data, $update = false) { if ($data['expected'] === TEST_BAD) { $old_hash = CDBHelper::getHash(self::SQL); } $data['fields']['Name'] = ($data['fields'] === []) ? '' : CTestArrayHelper::get($data, 'fields.Name', 'Item navigator '.microtime()); $this->page->login()->open('zabbix.php?action=dashboard.view&dashboardid='. self::$dashboardid[self::DASHBOARD_FOR_WIDGET_CREATE])->waitUntilReady(); $dashboard = CDashboardElement::find()->one(); $old_widget_count = $dashboard->getWidgets()->count(); $form = $update ? $dashboard->getWidget(self::$update_widget)->edit()->asForm() : $dashboard->edit()->addWidget()->asForm(); $form->fill(['Type' => CFormElement::RELOADABLE_FILL('Item navigator')]); if (array_key_exists('tags', $data)) { foreach ($data['tags'] as $entity => $values) { $this->setTagSelector('id:tags_table_'.$entity.'_tags'); $this->setTags($values); } } $form->fill($data['fields']); if (array_key_exists('group_by', $data)) { $this->getGroupByTable()->fill($data['group_by']); } if ($data['expected'] === TEST_GOOD) { $values = $form->getFields()->filter(CElementFilter::VISIBLE)->asValues(); } $form->submit(); // Trim leading and trailing spaces from expected results if necessary. if (CTestArrayHelper::get($data, 'trim', false)) { $data = CTestArrayHelper::trim($data); } if ($data['expected'] === TEST_BAD) { $this->assertMessage($data['expected'], null, $data['error']); $this->assertEquals($old_hash, CDBHelper::getHash(self::SQL)); COverlayDialogElement::find()->one()->close(); } else { // If name is empty string it is replaced by default widget name "Item navigator". $header = ($data['fields']['Name'] === '') ? 'Item navigator' : $data['fields']['Name']; if ($update) { self::$update_widget = $header; } COverlayDialogElement::ensureNotPresent(); $widget = $dashboard->getWidget($header); // Save Dashboard to ensure that widget is correctly saved. $dashboard->save()->waitUntilReady(); $this->assertMessage(TEST_GOOD, 'Dashboard updated'); // Check widgets count. $this->assertEquals($old_widget_count + ($update ? 0 : 1), $dashboard->getWidgets()->count()); // Check new widget update interval. $refresh = (CTestArrayHelper::get($data['fields'], 'Refresh interval') === 'Default (1 minute)') ? '1 minute' : (CTestArrayHelper::get($data['fields'], 'Refresh interval', '1 minute')); $this->assertEquals($refresh, $widget->getRefreshInterval()); // Check new widget form fields and values in frontend. $saved_form = $widget->edit(); $this->assertEquals($values, $saved_form->getFields()->filter(CElementFilter::VISIBLE)->asValues()); $saved_form->checkValue($data['fields']); if (array_key_exists('tags', $data)) { foreach ($data['tags'] as $entity => $values) { $this->setTagSelector('id:tags_table_'.$entity.'_tags'); $this->assertTags($values); } } // Close widget window and cancel editing the dashboard. COverlayDialogElement::find()->one()->close(); $dashboard->cancelEditing(); } } public static function getCancelData() { return [ // Cancel update widget. [ [ 'update' => true, 'save_widget' => true, 'save_dashboard' => false ] ], [ [ 'update' => true, 'save_widget' => false, 'save_dashboard' => true ] ], // Cancel create widget. [ [ 'save_widget' => true, 'save_dashboard' => false ] ], [ [ 'save_widget' => false, 'save_dashboard' => true ] ] ]; } /** * @dataProvider getCancelData */ public function testDashboardItemNavigatorWidget_Cancel($data) { $old_hash = CDBHelper::getHash(self::SQL); $new_name = 'Widget to be cancelled'; $this->page->login()->open('zabbix.php?action=dashboard.view&dashboardid='. self::$dashboardid[self::DEFAULT_DASHBOARD])->waitUntilReady(); $dashboard = CDashboardElement::find()->one()->edit(); $old_widget_count = $dashboard->getWidgets()->count(); // Start updating or creating a widget. if (CTestArrayHelper::get($data, 'update', false)) { $form = $dashboard->getWidget(self::DEFAULT_WIDGET)->edit(); } else { $form = $dashboard->addWidget()->asForm(); $form->fill(['Type' => CFormElement::RELOADABLE_FILL('Item navigator')]); } $form->fill([ 'Name' => $new_name, 'Refresh interval' => '15 minutes', 'Host tags' => 'Or', 'id:host_tags_0_tag' => 'host', 'id:host_tags_0_operator' => 'Does not contain', 'id:host_tags_0_value' => 'cancel', 'Item patterns' => 'available*', 'id:item_tags_0_tag' => 'item', 'id:item_tags_0_operator' => 'Does not contain', 'id:item_tags_0_value' => 'cancel', 'State' => 'Normal', 'Show problems' => 'All', 'Item limit' => '777' ]); $this->getGroupByTable()->fill([ ['attribute' => 'Host tag value', 'tag' => 'windows'], ['attribute' => 'Item tag value', 'tag' => 'memory'] ]); // Save or cancel widget. if (CTestArrayHelper::get($data, 'save_widget', false)) { $form->submit(); // Check that changes took place on the unsaved dashboard. $this->assertTrue($dashboard->getWidget($new_name)->isVisible()); } else { $dialog = COverlayDialogElement::find()->one(); $dialog->query('button:Cancel')->one()->click(); $dialog->ensureNotPresent(); if (CTestArrayHelper::get($data, 'update', false)) { foreach ([self::DEFAULT_WIDGET => true, $new_name => false] as $name => $valid) { $dashboard->getWidget($name, false)->isValid($valid); } } $this->assertEquals($old_widget_count, $dashboard->getWidgets()->count()); } // Save or cancel dashboard update. if (CTestArrayHelper::get($data, 'save_dashboard', false)) { $dashboard->save(); } else { $dashboard->cancelEditing(); } $this->assertEquals($old_hash, CDBHelper::getHash(self::SQL)); } public function testDashboardItemNavigatorWidget_Delete() { $this->page->login()->open('zabbix.php?action=dashboard.view&dashboardid='. self::$dashboardid[self::DEFAULT_DASHBOARD])->waitUntilReady(); $dashboard = CDashboardElement::find()->one()->edit(); $widget = $dashboard->getWidget(self::DELETE_WIDGET); $dashboard->deleteWidget(self::DELETE_WIDGET); $widget->waitUntilNotPresent(); $dashboard->save(); $this->assertMessage(TEST_GOOD, 'Dashboard updated'); // Check that widget is not present on dashboard. $this->assertFalse($dashboard->getWidget(self::DELETE_WIDGET, false)->isValid()); $this->assertEquals(0, CDBHelper::getCount('SELECT * FROM widget_field wf'. ' LEFT JOIN widget w'. ' ON w.widgetid=wf.widgetid'. ' WHERE w.name='.zbx_dbstr(self::DELETE_WIDGET) )); } /** * Row highlight check. */ public function testDashboardItemNavigatorWidget_RowHighlight() { $this->setWidgetConfiguration(self::$dashboardid[self::DEFAULT_DASHBOARD], self::DEFAULT_WIDGET, ['Item patterns' => '*memory in*']); $this->checkRowHighlight(self::DEFAULT_WIDGET, 'Available memory in %', true); CDashboardElement::find()->one()->save(); $this->checkRowHighlight(self::DEFAULT_WIDGET, 'Available memory in %'); } /** * Test function for assuring that all types of items are available in Item navigator widget. */ public function testDashboardItemNavigatorWidget_CheckAvailableItems() { $this->checkAvailableItems('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboardid[self::DEFAULT_DASHBOARD], 'Item navigator' ); } }