<?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 __DIR__.'/../../include/CLegacyWebTest.php';
require_once __DIR__.'/../../../include/items.inc.php';
require_once __DIR__.'/../../../include/classes/api/services/CItemGeneral.php';
require_once __DIR__.'/../../../include/classes/api/services/CItemPrototype.php';
require_once __DIR__.'/../behaviors/CMessageBehavior.php';

use Facebook\WebDriver\WebDriverBy;

/**
 * Test the creation of inheritance of new objects on a previously linked template.
 *
 * @backup items
 * TODO: The following annotation (ignoreBrowserErrors) is added to ignore JS errors generated by information type
 *       dropdown field when "on change" event is fired before "on focus" event is fired.
 * @ignoreBrowserErrors
 */
class testFormItemPrototype extends CLegacyWebTest {

	/**
	 * Attach MessageBehavior to the test.
	 */
	public function getBehaviors() {
		return [CMessageBehavior::class];
	}

	/**
	 * The name of the test host created in the test data set.
	 *
	 * @var string
	 */
	protected $host = 'Simple form test host';

	/**
	 * The id of the test host created in the test data set.
	 *
	 * @var string
	 */
	protected $hostid = 40001;

	/**
	 * The name of the test discovery rule created in the test data set on host.
	 *
	 * @var string
	 */
	protected $discoveryRule = 'testFormDiscoveryRule';

	/**
	 * The name of the test discovery rule created in the test data set on template.
	 *
	 * @var string
	 */
	protected $discoveryRuleTemplate = 'testInheritanceDiscoveryRule';


	// Returns layout data
	public static function layout() {
		return [
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Zabbix agent'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'key' => 'item-prototype-form1[{#KEY}]'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Zabbix agent',
					'value_type' => 'Numeric (unsigned)'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Zabbix agent',
					'value_type' => 'Numeric (unsigned)'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Zabbix agent',
					'value_type' => 'Numeric (unsigned)'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Zabbix agent',
					'value_type' => 'Numeric (float)'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Zabbix agent',
					'value_type' => 'Character'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Zabbix agent',
					'value_type' => 'Log'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Zabbix agent',
					'value_type' => 'Text'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Zabbix agent (active)'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Simple check'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'SNMP agent'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'SNMP agent',
					'value_type' => 'Numeric (float)'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'SNMP agent',
					'value_type' => 'Character'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'SNMP agent',
					'value_type' => 'Log'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'SNMP agent',
					'value_type' => 'Text'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'SNMP trap'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Zabbix internal'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Zabbix internal',
					'value_type' => 'Numeric (unsigned)'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Zabbix trapper'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'External check'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Database monitor'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'IPMI agent'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'SSH agent'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'SSH agent',
					'authtype' => 'Public key'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'SSH agent',
					'authtype' => 'Password'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'SSH agent',
					'value_type' => 'Numeric (unsigned)'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'SSH agent',
					'authtype' => 'Password',
					'value_type' => 'Character'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'TELNET agent'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'JMX agent'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Calculated'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Script'
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Browser'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Zabbix agent'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'key' => 'item-prototype-test1[{#KEY}]'
				]
			],
			[
				[
					'host' => 'Template inheritance test host',
					'key' => 'item-prototype-test1[{#KEY}]'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Zabbix agent',
					'value_type' => 'Numeric (unsigned)'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Zabbix agent',
					'value_type' => 'Numeric (unsigned)'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Zabbix agent',
					'value_type' => 'Numeric (unsigned)'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Zabbix agent',
					'value_type' => 'Numeric (float)'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Zabbix agent',
					'value_type' => 'Character'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Zabbix agent',
					'value_type' => 'Log'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Zabbix agent',
					'value_type' => 'Text'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Zabbix agent (active)'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Simple check'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'SNMP agent'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'SNMP agent',
					'value_type' => 'Numeric (float)'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'SNMP agent',
					'value_type' => 'Character'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'SNMP agent',
					'value_type' => 'Log'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'SNMP agent',
					'value_type' => 'Text'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'SNMP trap'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Zabbix internal'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Zabbix internal',
					'value_type' => 'Numeric (unsigned)'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Zabbix trapper'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'External check'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Database monitor'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'IPMI agent'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'SSH agent'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'SSH agent',
					'authtype' => 'Public key'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'SSH agent',
					'authtype' => 'Password'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'SSH agent',
					'value_type' => 'Numeric (unsigned)'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'SSH agent',
					'authtype' => 'Password',
					'value_type' => 'Character'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'TELNET agent'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'JMX agent'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Calculated'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Script'
				]
			],
			[
				[
					'template' => 'Inheritance test template',
					'type' => 'Browser'
				]
			],
			[
				[
					'host' => 'Template inheritance test host',
					'hostTemplate' => 'Inheritance test template',
					'key' => 'item-prototype-preprocessing[{#KEY}]',
					'preprocessing' => true
				]
			],
			[
				[
					'host' => 'Simple form test host',
					'type' => 'Dependent item',
					'value_type' => 'Numeric (unsigned)'
				]
			]
		];
	}

	/**
	 * @dataProvider layout
	 */
	public function testFormItemPrototype_CheckLayout($data) {
		$context = array_key_exists('host', $data) ? 'host' : 'template';
		$host_name = array_key_exists('host', $data) ? $data['host'] : $data['template'];

		$dbResult = DBselect('SELECT hostid,status FROM hosts WHERE host='.zbx_dbstr($host_name));
		$host_info = DBfetch($dbResult);

		$this->assertNotEquals($host_info, null);

		$hostid = $host_info['hostid'];
		$status = $host_info['status'];

		if (isset($data['key'])) {
			$dbResult = DBselect(
				'SELECT itemid,templateid'.
				' FROM items'.
				' WHERE hostid='.$hostid.
					' AND key_='.zbx_dbstr($data['key'])
			);
			$template_info = DBfetch($dbResult);
			$this->assertNotEquals($template_info, null);

			$itemid = $template_info['itemid'];
			if (0 != $template_info['templateid'])
				$templateid = $template_info['templateid'];
		}

		if ($status == HOST_STATUS_TEMPLATE) {
			$discoveryRule = $this->discoveryRuleTemplate;
		}
		else {
			if (isset($templateid)) {
				$discoveryRule = $this->discoveryRuleTemplate;
			}
			else {
				$discoveryRule = $this->discoveryRule;
			}
		}

		$dbResult = DBselect(
			'SELECT itemid'.
			' FROM items'.
			' WHERE hostid='.$hostid.
				' AND name='.zbx_dbstr($discoveryRule).
				' AND flags='.ZBX_FLAG_DISCOVERY_RULE
		);
		$dbRow = DBfetch($dbResult);

		$this->assertNotEquals($dbRow, null);

		$discoveryid = $dbRow['itemid'];

		$this->page->login()->open('zabbix.php?action=item.prototype.list&parent_discoveryid='.$discoveryid.'&context='.$context);
		$this->page->assertTitle('Configuration of item prototypes');
		$this->page->assertHeader('Item prototypes');

		if (isset($itemid)) {
			$this->query('link:'.CDBHelper::getValue('SELECT name from items WHERE itemid='.$itemid))->one()->click();
		}
		else {
			$this->query('button:Create item prototype')->one()->click();
		}

		$dialog = COverlayDialogElement::find()->one()->waitUntilReady();
		$this->assertEquals(isset($itemid) ? 'Item prototype' : 'New item prototype', $dialog->getTitle());
		$form = $dialog->asForm();
		$dialog_footer = $dialog->getFooter();

		if (isset($templateid)) {
			$this->zbxTestTextPresent('Parent items');
			if (isset($data['hostTemplate'])) {
				$this->zbxTestAssertElementPresentXpath("//a[text()='".$data['hostTemplate']."']");
			}
		}
		else {
			$this->zbxTestTextNotPresent('Parent items');
		}

		$this->assertTrue($form->getField('Name')->isDisplayed());
		$this->assertEquals(255, $form->getField('Name')->getAttribute('maxlength'));
		$this->assertEquals('true', $form->getField('Name')->getAttribute('autofocus'));

		$this->assertTrue($form->getField('Type')->isDisplayed());
		$type_field = $form->getField('Type')->asDropdown();
		if (!isset($templateid)) {
			$options = $type_field->getOptions()->asText();
			$this->assertEquals($options, [
				'Zabbix agent',
				'Zabbix agent (active)',
				'Simple check',
				'SNMP agent',
				'SNMP trap',
				'Zabbix internal',
				'Zabbix trapper',
				'External check',
				'Database monitor',
				'HTTP agent',
				'IPMI agent',
				'SSH agent',
				'TELNET agent',
				'JMX agent',
				'Calculated',
				'Dependent item',
				'Script',
				'Browser'
			]);
			if (isset($data['type'])) {
				$type_field->select($data['type']);
				$type = $data['type'];
			}
			else {
				$type = $type_field->getText();
			}
		}
		else {
			$this->assertEquals('true', $form->getField('Type')->getAttribute('readonly'));
			$type = $type_field->getText();
		}

		$this->assertTrue($form->getField('Key')->isDisplayed());
		$this->assertEquals(2048, $form->getField('Key')->getAttribute('maxlength'));

		if (!isset($templateid)) {
			$this->assertTrue($form->query('xpath://button[@class="js-select-key btn-grey"]')->one()->isDisplayed());
		}
		else {
			$this->assertEquals('true', $form->getField('Key')->getAttribute('readonly'));
		}

		if ($type == 'Database monitor' && !isset($itemid)) {
			$this->zbxTestAssertElementValue('key', 'db.odbc.select[<unique short description>,<dsn>,<connection string>]');
		}

		if ($type == 'SSH agent' && !isset($itemid)) {
			$this->zbxTestAssertElementValue('key', 'ssh.run[<unique short description>,<ip>,<port>,<encoding>,<ssh options>,<subsystem>]');
		}

		if ($type == 'TELNET agent' && !isset($itemid)) {
			$this->zbxTestAssertElementValue('key', 'telnet.run[<unique short description>,<ip>,<port>,<encoding>]');
		}

		if ($type == 'JMX agent' && !isset($itemid)) {
			$this->zbxTestAssertElementValue('key', '');
			$this->assertTrue($dialog->query('button:Select')->one()->isEnabled());
		}

		if ($status != HOST_STATUS_TEMPLATE) {
			$interfaceType = itemTypeInterface($this->zbxTestGetValue('//*[@id="type"]'));
			switch ($interfaceType) {
				case INTERFACE_TYPE_SNMP :
				case INTERFACE_TYPE_IPMI :
				case INTERFACE_TYPE_AGENT :
				case INTERFACE_TYPE_ANY :
				case INTERFACE_TYPE_JMX :
				case INTERFACE_TYPE_OPT :
					$this->zbxTestTextPresent('Host interface');
					$dbInterfaces = DBselect(
						'SELECT type,ip,port'.
						' FROM interface'.
						' WHERE hostid='.$hostid.
							(($interfaceType == INTERFACE_TYPE_ANY || $interfaceType === INTERFACE_TYPE_OPT) ? '' : ' AND type='.$interfaceType)
					);
					while ($row = DBfetch($dbInterfaces)) {
						$data[] = [$row];
					}
					$dbInterfaces = $data[0];
					if ($dbInterfaces != null) {
						foreach ($dbInterfaces as $host_interface) {
							$this->zbxTestAssertElementPresentXpath('//z-select[@id="interface-select"]//li[text()="'.
									$host_interface['ip'].':'.$host_interface['port'].'"]');
						}
					}
					else {
						$this->zbxTestTextPresent('No interface found');
						$this->zbxTestAssertNotVisibleId('interface-select');
					}
					break;
				default:
					$this->zbxTestTextNotVisible(['Host interface', 'No interface found']);
					$this->zbxTestAssertNotVisibleId('interface-select');
					break;
			}
		}

		if (isset($templateid)) {
			$value_type = $form->getField('Type of information')->asDropdown()->getText();
		}
		elseif (isset($data['value_type'])) {
			$form->getField('Type of information')->asDropdown()->select($data['value_type']);
			$value_type = $data['value_type'];
		}
		else {
			$value_type = $form->getField('Type of information')->asDropdown()->getText();
		}

		if ($type == 'SSH agent') {
			if (isset($data['authtype'])) {
				$form->getField('Authentication method')->asDropdown()->select($data['authtype']);
				$authtype = $data['authtype'];
			}
			else {
				$authtype = $form->getField('Authentication method')->asDropdown()->getText();
			}
		}
		else {
			$authtype = null;
		}

		if ($type == 'Database monitor') {
			$this->assertTrue($form->getField('SQL query')->isDisplayed());
			$this->assertEquals(7, $form->getField('SQL query')->getAttribute('rows'));
			$this->zbxTestAssertElementValue('params_ap', '');
		}
		else {
			$this->assertFalse($form->query('id:js-item-sql-query-label')->one()->isDisplayed());
			$this->assertFalse($form->query('id:params_ap')->one()->isDisplayed());
		}

		if ($type == 'SSH agent' || $type == 'TELNET agent' ) {
			$this->assertTrue($form->getField('Executed script')->isDisplayed());
			$this->assertEquals(7, $form->getField('Executed script')->getAttribute('rows'));
		}
		else {
			$this->assertFalse($form->query('id:js-item-executed-script-label')->one()->isDisplayed());
			$this->assertFalse($form->query('id:params_es')->one()->isDisplayed());
		}

		if ($type == 'Calculated') {
			$this->assertTrue($form->getField('Formula')->isDisplayed());
			$this->assertEquals(7, $form->getField('Formula')->getAttribute('rows'));
		}
		else {
			$this->assertFalse($form->query('id:js-item-formula-label')->one()->isDisplayed());
			$this->assertFalse($form->query('id:params_f')->one()->isDisplayed());
		}

		if ($type == 'IPMI agent') {
			$this->assertTrue($form->getField('IPMI sensor')->isDisplayed());
			$this->assertEquals(128, $form->getField('IPMI sensor')->getAttribute('maxlength'));
		}
		else {
			$this->zbxTestTextNotVisible('IPMI sensor');
			$this->assertFalse($form->query('id:ipmi_sensor')->one()->isDisplayed());
		}

		if ($type == 'SSH agent') {
			$this->assertTrue($form->query('id:authtype')->one()->isDisplayed());
			$this->assertEquals(['Password', 'Public key'], $form->getField('Authentication method')->asDropdown()
					->getOptions()->asText()
			);
		}
		else {
			$this->assertFalse($form->query('id:authtype')->one()->isDisplayed());
			$this->assertFalse($form->query('id:js-item-authtype-label')->one()->isDisplayed());
		}

		if ($type == 'Simple check' || $type == 'SSH agent' || $type == 'TELNET agent' || $type == 'JMX agent'
				|| $type == 'Database monitor') {
			$this->assertTrue($form->query('id', ['username', 'password'])->one()->isDisplayed());
			$this->assertEquals(255, $form->getField('User name')->getAttribute('maxlength'));

			if ($authtype == 'Public key') {
				$this->assertTrue($form->getField('Key passphrase')->isDisplayed());
				$this->assertEquals(255, $form->getField('Key passphrase')->getAttribute('maxlength'));
				$this->assertFalse($form->query('name:password')->one()->isDisplayed());
			}
			else {
				$this->assertTrue($form->getField('Password')->isDisplayed());
				$this->assertEquals(255, $form->getField('Password')->getAttribute('maxlength'));
			}
		}
		else {
			$this->assertFalse($form->query('id', ['username', 'password'])->one()->isDisplayed());
		}

		if	($type == 'SSH agent' && $authtype == 'Public key') {
			$this->assertTrue($form->getField('Public key file')->isDisplayed());
			$this->assertTrue($form->getField('Private key file')->isDisplayed());
			$this->assertEquals(64, $form->getField('Public key file')->getAttribute('maxlength'));
			$this->assertEquals(64, $form->getField('Private key file')->getAttribute('maxlength'));
		}
		else {
			$this->assertFalse($form->query('id', ['publickey', 'privatekey'])->one()->isDisplayed());
		}

		if	($type === 'SNMP agent') {
			$this->assertTrue($form->getField('SNMP OID')->isDisplayed());
			$this->assertEquals(512, $form->getField('SNMP OID')->getAttribute('maxlength'));
			if (!isset($itemid)) {
				$this->assertEquals('walk[OID1,OID2,...]', $form->getField('SNMP OID')->getAttribute('placeholder'));
			}

			//Check hintbox.
			$hint_text = "Field requirements:".
				"\nwalk[OID1,OID2,...] - to retrieve a subtree".
				"\nget[OID] - to retrieve a single value".
				"\nOID - (legacy) to retrieve a single value synchronously, optionally combined with other values";

			$form->getLabel('SNMP OID')->query('xpath:./button[@data-hintbox]')->one()->click();
			$hint = $this->query('xpath://div[@data-hintboxid]')->waitUntilPresent();
			$this->assertEquals($hint_text, $hint->one()->getText());
			$hint->one()->query('xpath:.//button[@class="btn-overlay-close"]')->one()->click();
			$hint->waitUntilNotPresent();
		}
		else {
			$this->assertFalse($form->getField('SNMP OID')->isDisplayed());
		}

		if (in_array($type, ['Script', 'Browser'])) {
			// Check parameters table layout.
			$parameters_table = $form->getField('Parameters')->asTable();
			$this->assertSame(['Name', 'Value', ''], $parameters_table->getHeadersText());

			$this->assertEquals(['Remove', 'Add'], $parameters_table->query('tag:button')->all()
					->filter(CElementFilter::CLICKABLE)->asText()
			);

			foreach(['parameters[0][name]' => 255, 'parameters[0][value]' => 2048] as $input_name => $maxlength) {
				$input = $parameters_table->query('name', $input_name)->one();
				$this->assertEquals($maxlength, $input->getAttribute('maxlength'));
				$this->assertEquals('', $input->getValue());
			}

			// Check Script field.
			$script_values = [
				'Script' => '',
				'Browser' => "var browser = new Browser(Browser.chromeOptions());\n\n".
						"try {\n".
						" browser.navigate(\"https://example.com\");\n".
						" browser.collectPerfEntries();\n".
						"}\n".
						"finally {\n".
						" return JSON.stringify(browser.getResult());\n".
						"}"
			];

			$this->assertTrue($form->isRequired('Script'));
			$script_field = $form->getField('Script');
			$this->assertEquals('script', $script_field->query('xpath:.//input[@type="text"]')->one()
					->getAttribute('placeholder')
			);

			$script_dialog = $script_field->edit();
			$this->assertEquals('JavaScript', $script_dialog->getTitle());
			$script_input = $script_dialog->query('xpath:.//textarea')->one();

			foreach (['placeholder' => 'return value', 'maxlength' => 65535] as $attribute => $value) {
				$this->assertEquals($value, $script_input->getAttribute($attribute));
			}
			$this->assertEquals($script_values[$type], $script_input->getText());
			$script_dialog->close();
		}

		switch ($type) {
			case 'Zabbix agent':
			case 'Zabbix agent (active)':
			case 'Simple check':
			case 'SNMP agent':
			case 'Zabbix internal':
			case 'External check':
			case 'Database monitor':
			case 'IPMI agent':
			case 'SSH agent':
			case 'TELNET agent':
			case 'JMX agent':
			case 'Calculated':
			case 'Script':
			case 'Browser':
				$this->assertTrue($form->getField('Update interval')->isDisplayed());
				$this->assertEquals(255, $form->getField('Update interval')->getAttribute('maxlength'));
				if (!isset($itemid)) {
					$form->checkValue(['Update interval' => '1m']);
				}
				break;
			default:
				$this->assertFalse($form->getField('Update interval')->isDisplayed());
		}

		$value_types = ($type === 'Dependent item')
			? ['Numeric (unsigned)', 'Numeric (float)', 'Character', 'Log', 'Text', 'Binary']
			: ['Numeric (unsigned)', 'Numeric (float)', 'Character', 'Log', 'Text'];

		if (!isset($templateid)) {
			$this->assertEquals($value_types, $form->getField('Type of information')->asDropdown()->getOptions()->asText());

			foreach (['Numeric (unsigned)', 'Numeric (float)', 'Character', 'Log', 'Text'] as $info_type) {
				$this->zbxTestIsEnabled('//*[@id="value_type"]//li[text()='.CXPathHelper::escapeQuotes($info_type).']');
			}
		}

		if (!isset($templateid)) {
			$this->zbxTestDropdownAssertSelected('value_type', $value_type);
			$this->zbxTestIsEnabled("//*[@id='value_type']//li[text()='Numeric (unsigned)']");
			$this->zbxTestIsEnabled("//*[@id='value_type']//li[text()='Numeric (float)']");
		}

		if ($value_type === 'Numeric (float)' || ($value_type == 'Numeric (unsigned)')) {
			$this->assertEquals(255, $form->getField('Units')->getAttribute('maxlength'));
			if(isset($templateid)) {
				$this->assertEquals('true', $form->getField('Units')->getAttribute('readonly'));
			}
		}
		else {
			$this->assertFalse($form->query('id:units')->one()->isDisplayed());
		}

		// Custom intervals field isn't visible for some item types.
		if (in_array($type, ['SNMP trap', 'Zabbix trapper', 'Dependent item'])) {
			$this->assertFalse($form->getField('Custom intervals')->isDisplayed());
			$this->assertFalse($form->query("xpath://div[@id='js-item-flex-intervals-field']//button[@class='btn-link element-table-add']")
					->one()->isDisplayed());
		}
		else {
			$this->zbxTestTextPresent(['Custom intervals', 'Interval',  'Period', '']);
			$this->assertTrue($form->getField('Custom intervals')->isDisplayed());

			$this->zbxTestTextPresent(['Flexible', 'Scheduling', 'Update interval']);
			$this->assertEquals(255, $form->getField('id:delay_flex_0_delay')->getAttribute('maxlength'));
			$this->assertEquals('50s', $form->getField('id:delay_flex_0_delay')->getAttribute('placeholder'));

			$this->assertEquals(255, $form->getField('id:delay_flex_0_period')->getAttribute('maxlength'));
			$this->assertEquals('1-7,00:00-24:00', $form->getField('id:delay_flex_0_period')
					->getAttribute('placeholder')
			);

			$this->assertTrue($form->query("xpath://div[@id='js-item-flex-intervals-field']//button[@class='btn-link element-table-add']")
					->one()->isClickable()
			);
		}

		$this->assertTrue($form->getField('History')->isDisplayed());
		$this->assertEquals(255, $form->getField('History')->getAttribute('maxlength'));
		$this->assertEquals('31d', $form->getField('History')->getAttribute('value'));

		if (!isset($itemid)) {
			$this->assertEquals('31d', $form->getField('History')->getAttribute('value'));
		}

		if ($value_type == 'Numeric (unsigned)' || $value_type == 'Numeric (float)') {
			$this->assertTrue($form->getField('Trends')->isDisplayed());
			$this->assertEquals(255, $form->getField('Trends')->getAttribute('maxlength'));
			if (!isset($itemid)) {
				$this->assertEquals('365d', $form->getField('Trends')->getValue());
			}
		}
		else {
			$this->assertFalse($form->getField('Trends')->isDisplayed());
		}

		if ($value_type == 'Numeric (float)' || $value_type == 'Numeric (unsigned)' || $value_type == 'Character') {
			$this->zbxTestTextPresent('Value mapping');
			$valuemap_field = $form->getField('Value mapping');
			$this->assertTrue($valuemap_field->isDisplayed());
			if (!isset($templateid)) {
				$this->assertEquals('', $valuemap_field->getValue());

				$db_valuemap = [];
				$valuemap_result = DBselect('SELECT name FROM valuemap WHERE hostid='.$host_info['hostid']);
				while ($row = DBfetch($valuemap_result)) {
					$db_valuemap[] = $row['name'];
				}
				$db_mappings = CDBHelper::getAll('SELECT vm.name, m.sortorder, m.value, m.newvalue FROM valuemap vm INNER JOIN'.
						' valuemap_mapping m ON m.valuemapid = vm.valuemapid WHERE vm.hostid='.$host_info['hostid'].
						' ORDER BY vm.name, m.sortorder');

				$valuemap_field->edit();
				$valuemap_overlay = COverlayDialogElement::find()->all()->last()->waitUntilReady();
				if ($db_valuemap !== []) {
					$this->assertEquals('Value mapping', $valuemap_overlay->getTitle());
					$valuemap_table = $valuemap_overlay->query('class:list-table')->one()->asTable();
					$this->assertEquals(['Name', 'Mapping'], $valuemap_table->getHeadersText());

					$expected_count = (count($db_valuemap) > 3) ? 3 : count($db_valuemap);
					$table_rows = $valuemap_table->getRows();
					$this->assertEquals($expected_count, $table_rows->count());
					foreach($table_rows as $value_mapping) {
						$valuemap_name = ltrim($value_mapping->getColumn('Name')->getText(), $host_name.': ');
						$this->assertTrue(in_array($valuemap_name, $db_valuemap));

						$mappings = [];
						$i = 0;
						foreach ($db_mappings as $db_mapping) {
							if ($db_mapping['name'] === $valuemap_name) {
								if ($i < 3) {
									$mappings[] = '='.$db_mapping['value'].' ⇒ '.$db_mapping['newvalue'];
									$i++;
								}
								else {
									$mappings[] = '…';

									break;
								}
							}
						}
						// Transform newlines in value map table text.
						$source = $value_mapping->getColumn('Mapping')->getText();
						$text = rtrim(preg_replace("/(.*)\n⇒\n(.*)\n?/", "\\1 ⇒ \\2\n", $source), "\n");
						$this->assertEquals(implode("\n", $mappings), $text);
					}
				}
				else {
					$this->assertEquals('No data found', $valuemap_overlay->query('class:nothing-to-show')->one()->getText());
				}
				$valuemap_overlay->getFooter()->query('button:Cancel')->one()->click();
			}
			else {
				$this->assertTrue($valuemap_field->isValid());
				$this->assertFalse($valuemap_field->isEnabled());
			}
		}
		else {
			$this->assertFalse($form->getField('Value mapping')->isDisplayed());
		}

		if ($type == 'Zabbix trapper') {
			$this->assertTrue($form->getField('Allowed hosts')->isDisplayed());
			$this->assertEquals(255, $form->getField('Allowed hosts')->getAttribute('maxlength'));
		}
		else {
			$this->assertFalse($form->getField('Allowed hosts')->isDisplayed());
		}

		if ($value_type == 'Log') {
			$this->assertTrue($form->getField('Log time format')->isDisplayed());
			$this->assertEquals(64, $form->getField('Log time format')->getAttribute('maxlength'));
		}
		else {
			$this->assertFalse($form->getField('Log time format')->isDisplayed());
		}

		$this->zbxTestTextNotPresent(['Applications','New application']);
		$this->assertTrue($form->getField('Description')->isDisplayed());
		$this->assertEquals(7, $form->getField('Description')->getAttribute('rows'));
		$this->assertTrue($form->getField('Create enabled')->asCheckbox()->isSelected());
		$this->assertEquals('Cancel', $dialog_footer->query('button:Cancel')->one()->getText());

		if (isset($itemid)) {
			$this->assertTrue($dialog_footer->query('button:Clone')->one()->isClickable());
		}
		else {
			$this->assertTrue($dialog_footer->query('button:Add')->one()->isDisplayed());
			$this->assertEquals(0, $dialog_footer->query('button:Clone')->all()->filter(CElementFilter::CLICKABLE)
					->count()
			);
		}

		if ((isset($itemid) && !isset($templateid))) {
			$this->assertTrue($dialog_footer->query('button:Delete')->one()->isClickable());
			$this->assertTrue($dialog_footer->query('button:Update')->one()->isClickable());
		}
		elseif (isset($templateid)) {
			$this->assertFalse($dialog_footer->query('button:Delete')->one()->isEnabled());
		}
		else {
			$this->assertEquals(0, $dialog_footer->query('button:Delete')->all()->filter(CElementFilter::CLICKABLE)
					->count()
			);
		}

		if (isset($templateid) && array_key_exists('preprocessing', $data)) {
			$form->selectTab('Preprocessing');
			$dbResult = DBselect('SELECT * FROM item_preproc WHERE itemid='.$itemid);
			$itemsPreproc = DBfetchArray($dbResult);
			foreach ($itemsPreproc as $itemPreproc) {
				// The array of allowed types must be synced with CItemPrototype::SUPPORTED_PREPROCESSING_TYPES.
				$preprocessing_type = get_preprocessing_types($itemPreproc['type'], false,
					CItemPrototype::SUPPORTED_PREPROCESSING_TYPES
				);
				$this->zbxTestAssertAttribute("//z-select[@id='preprocessing_".($itemPreproc['step']-1)."_type']", 'readonly');
				$this->zbxTestDropdownAssertSelected("preprocessing_".($itemPreproc['step']-1)."_type", $preprocessing_type);
				if ((1 <= $itemPreproc['type']) && ($itemPreproc['type'] <= 4)) {
					$this->zbxTestAssertAttribute("//input[@id='preprocessing_".($itemPreproc['step']-1)."_params_0']", 'readonly');
					$this->zbxTestAssertElementValue("preprocessing_".($itemPreproc['step']-1)."_params_0", $itemPreproc['params']);
				}
				elseif ($itemPreproc['type'] == 5) {
					$reg_exp = preg_split("/\n/", $itemPreproc['params']);
					$this->zbxTestAssertAttribute("//input[@id='preprocessing_".($itemPreproc['step']-1)."_params_0']", 'readonly');
					$this->zbxTestAssertAttribute("//input[@id='preprocessing_".($itemPreproc['step']-1)."_params_1']", 'readonly');
					$this->zbxTestAssertElementValue("preprocessing_".($itemPreproc['step']-1)."_params_0", $reg_exp[0]);
					$this->zbxTestAssertElementValue("preprocessing_".($itemPreproc['step']-1)."_params_1", $reg_exp[1]);
				}
			}
		}

		$dialog->close();
	}

	// Returns update data
	public static function update() {
		return CDBHelper::getDataProvider(
			'select * from items'.
			' where hostid = 40001 and key_ LIKE \'item-prototype-form%\''
		);
	}

	/**
	 * @dataProvider update
	 */
	public function testFormItemPrototype_SimpleUpdate($data) {
		$sqlItems = "select itemid, hostid, name, key_, delay from items order by itemid";
		$oldHashItems = CDBHelper::getHash($sqlItems);

		$this->page->login()->open('zabbix.php?action=item.prototype.list&parent_discoveryid=133800&context=host');
		$this->query('link:'.$data['name'])->one()->click();
		COverlayDialogElement::find()->one()->waitUntilReady()->getFooter()->query('button:Update')->one()->click();
		COverlayDialogElement::ensureNotPresent();

		$this->zbxTestCheckTitle('Configuration of item prototypes');
		$this->zbxTestWaitUntilMessageTextPresent('msg-good', 'Item prototype updated');
		$this->zbxTestTextPresent([$data['name'], $this->discoveryRule]);

		$this->assertEquals($oldHashItems, CDBHelper::getHash($sqlItems));
	}

	// Returns create data
	public static function create() {
		return [
			// #0
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'Checksum of $1',
					'key' => 'vfs.file.cksum[/sbin/shutdown,{#KEY}]',
					'dbName' => 'Checksum of $1',
					'dbCheck' => true,
					'formCheck' =>true
				]
			],
			// #1
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Checksum of $1',
					'key' => 'vfs.file.cksum[/sbin/shutdown]',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/key_": must contain at least one low-level discovery macro.'
					]
				]
			],
			// #2 Duplicate item
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Checksum of $1',
					'key' => 'vfs.file.cksum[/sbin/shutdown,{#KEY}]',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'An item prototype with key "vfs.file.cksum[/sbin/shutdown,{#KEY}]" already exists on the host'
					]
				]
			],
			// #3 Item name is missing
			[
				[
					'expected' => TEST_BAD,
					'key' =>'item-name-missing[{#KEY}]',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Incorrect value for field "name": cannot be empty.'
					]
				]
			],
			// #4 Item key is missing
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item name',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Incorrect value for field "key": cannot be empty.'
					]
				]
			],
			// #5 Empty timedelay
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item delay',
					'key' => 'item-delay-test[{#KEY}]',
					'delay' => 0,
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/delay": cannot be equal to zero without custom intervals.'
					]
				]
			],
			// #6 Incorrect timedelay
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item delay',
					'key' => 'item-delay-test[{#KEY}]',
					'delay' => '-30',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Incorrect value for field "delay": a time unit is expected'
					]
				]
			],
			// #7 Incorrect timedelay
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item delay',
					'key' => 'item-delay-test[{#KEY}]',
					'delay' => 86401,
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/delay": value must be one of 0-86400.'
					]
				]
			],
			// #8 Empty time flex period
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item flex',
					'key' => 'item-flex-test[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '']
					],
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid interval "".'
					]
				]
			],
			// #9 Incorrect flex period
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item flex',
					'key' => 'item-flex-test[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '1-11,00:00-24:00']
					],
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid interval "1-11,00:00-24:00".'
					]
				]
			],
			// #10 Incorrect flex period
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item flex',
					'key' => 'item-flex-test[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '1-7,00:00-25:00', 'instantCheck' => true]
					],
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid interval "1-7,00:00-25:00".'
					]
				]
			],
			// #11 Incorrect flex period
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item flex',
					'key' => 'item-flex-test[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '1-7,24:00-00:00']
					],
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid interval "1-7,24:00-00:00".'
					]
				]
			],
			// #12 Incorrect flex period
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item flex',
					'key' => 'item-flex-test[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '1,00:00-24:00;2,00:00-24:00']
					],
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid interval "1,00:00-24:00;2,00:00-24:00".'
					]
				]
			],
			// #13 Multiple flex periods
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'Item flex',
					'key' => 'item-flex-test[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '1,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '2,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '1,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '2,00:00-24:00']
					]
				]
			],
			// #14 Delay combined with flex periods
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item flex',
					'key' => 'item-flex-delay[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 0, 'flexTime' => '1,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '2,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '3,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '4,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '5,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '6,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '7,00:00-24:00']
					],
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/delay": non-active intervals cannot fill the entire time.'
					]
				]
			],
			// #15 Delay combined with flex periods
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'Item flex1',
					'key' => 'item-flex-delay1[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '1,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '2,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '3,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '4,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '5,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '6,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '7,00:00-24:00']
					]
				]
			],
			// #16 Delay combined with flex periods
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item flex',
					'key' => 'item-flex-delay[{#KEY}]',
					'delay' => 0,
					'flexPeriod' => [
						['flexDelay' => 0, 'flexTime' => '1,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '2,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '3,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '4,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '5,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '6,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '7,00:00-24:00']
					],
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/delay": must have at least one interval greater than 0.'
					]
				]
			],
			// #17 Delay combined with flex periods
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'Item flex2',
					'key' => 'item-flex-delay2[{#KEY}]',
					'delay' => 0,
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '1-5,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '6-7,00:00-24:00']
					],
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #18 Delay combined with flex periods
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item flex',
					'key' => 'item-flex-delay[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 0, 'flexTime' => '1-5,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '6-7,00:00-24:00']
					],
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/delay": non-active intervals cannot fill the entire time.'
					]
				]
			],
			// #19 Delay combined with flex periods
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'Item flex',
					'key' => 'item-flex-delay3[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '1-5,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '6-7,00:00-24:00']
					]
				]
			],
			// #20 Delay combined with flex periods
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'Item flex',
					'key' => 'item-flex-delay4[{#KEY}]',
					'delay' => 0,
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '1-7,00:00-24:00']
					]
				]
			],
			// #21 Delay combined with flex periods
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item flex',
					'key' => 'item-flex-delay[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 0, 'flexTime' => '1-7,00:00-24:00']
					],
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/delay": non-active intervals cannot fill the entire time.'
					]
				]
			],
			// #22 Delay combined with flex periods
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'Item flex',
					'key' => 'item-flex-delay5[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '1-7,00:00-24:00']
					]
				]
			],
			// #23 Delay combined with flex periods
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item flex',
					'key' => 'item-flex-delay[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 0, 'flexTime' => '1-5,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '6-7,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '1-5,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '6-7,00:00-24:00']
					],
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/delay": non-active intervals cannot fill the entire time.'
					]
				]
			],
			// #24 Delay combined with flex periods
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item flex',
					'key' => 'item-flex-delay[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '1-5,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '6-7,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '1-5,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '6-7,00:00-24:00']
					],
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/delay": non-active intervals cannot fill the entire time.'
					]
				]
			],
			// #25 Delay combined with flex periods
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item flex',
					'key' => 'item-flex-delay[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '1-7,00:00-24:00'],
						['flexDelay' => 0, 'flexTime' => '1-7,00:00-24:00']
					],
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/delay": non-active intervals cannot fill the entire time.'
					]
				]
			],
			// #26 Delay combined with flex periods
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item flex',
					'key' => 'item-flex-delay[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 0, 'flexTime' => '1-7,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '1-7,00:00-24:00']
					],
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/delay": non-active intervals cannot fill the entire time.'
					]
				]
			],
			// #27 Delay combined with flex periods
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'Item flex',
					'key' => 'item-flex-delay6[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 0, 'flexTime' => '1,00:00-24:00', 'remove' => true],
						['flexDelay' => 0, 'flexTime' => '2,00:00-24:00', 'remove' => true],
						['flexDelay' => 0, 'flexTime' => '3,00:00-24:00', 'remove' => true],
						['flexDelay' => 0, 'flexTime' => '4,00:00-24:00', 'remove' => true],
						['flexDelay' => 0, 'flexTime' => '5,00:00-24:00', 'remove' => true],
						['flexDelay' => 0, 'flexTime' => '6,00:00-24:00', 'remove' => true],
						['flexDelay' => 0, 'flexTime' => '7,00:00-24:00', 'remove' => true],
						['flexDelay' => 50, 'flexTime' => '1,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '2,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '3,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '4,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '5,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '6,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '7,00:00-24:00']
					]
				]
			],
			// #28 Delay combined with flex periods
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'Item flex',
					'key' => 'item-flex-delay7[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 0, 'flexTime' => '1-7,00:00-24:00', 'remove' => true],
						['flexDelay' => 50, 'flexTime' => '1-7,00:00-24:00']
					]
				]
			],
			// #29 Delay combined with flex periods
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'Item flex Check',
					'key' => 'item-flex-delay8[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 0, 'flexTime' => '1-5,00:00-24:00', 'remove' => true],
						['flexDelay' => 0, 'flexTime' => '6-7,00:00-24:00', 'remove' => true],
						['flexDelay' => 50, 'flexTime' => '1-5,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '6-7,00:00-24:00']
					],
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #30 Seven flexfields - save OK
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'Item flex-maximum save OK',
					'key' => 'item-flex-maximum-save[{#KEY}]',
					'flexPeriod' => [
						['flexDelay' => 50, 'flexTime' => '1-7,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '1-7,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '1-7,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '1-7,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '1-7,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '1-7,00:00-24:00'],
						['flexDelay' => 50, 'flexTime' => '1-7,00:00-24:00']
					],
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #31 History
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item history',
					'key' => 'item-history-empty[{#KEY}]',
					'history' => ' ',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/history": cannot be empty.'
					]
				]
			],
			// #32 History
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item history',
					'key' => 'item-history-test[{#KEY}]',
					'history' => 3599,
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/history": value must be one of 0, 3600-788400000.'
					]
				]
			],
			// #33 History
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item history',
					'key' => 'item-history-test[{#KEY}]',
					'history' => 788400001,
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/history": value must be one of 0, 3600-788400000.'
					]
				]
			],
			// #34 History
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item history',
					'key' => 'item-history-test[{#KEY}]',
					'history' => '-1',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/history": value must be one of 0, 3600-788400000.'
					]
				]
			],
			// #35 Trends
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item trends',
					'key' => 'item-trends-empty[{#KEY}]',
					'trends' => ' ',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/trends": cannot be empty.'
					]
				]
			],
			// #36 Trends
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item trends',
					'key' => 'item-trends-test[{#KEY}]',
					'trends' => '-1',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/trends": value must be one of 0, 86400-788400000.'
					]
				]
			],
			// #37 Trends
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item trends',
					'key' => 'item-trends-test[{#KEY}]',
					'trends' => 86399,
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/trends": value must be one of 0, 86400-788400000.'
					]
				]
			],
			// #38 Trends
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Item trends',
					'key' => 'item-trends-test[{#KEY}]',
					'trends' => 788400001,
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/trends": value must be one of 0, 86400-788400000.'
					]
				]
			],
			// #39
			[
				[
					'expected' => TEST_GOOD,
					'name' => '!@#$%^&*()_+-=[]{};:"|,./<>?',
					'key' => 'item-symbols-test[{#KEY}]',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #40
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'itemSimple',
					'key' => 'key-template-simple[{#KEY}]',
					'formCheck' => true,
					'dbCheck' => true
				]
			],
			// #41
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'itemName',
					'key' => 'key-template-item[{#KEY}]',
					'formCheck' => true
				]
			],
			//#42
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'itemTrigger',
					'key' => 'key-template-trigger[{#KEY}]',
					'formCheck' => true,
					'dbCheck' => true,
					'remove' => true
				]
			],
			// #43
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'itemRemove',
					'key' => 'key-template-remove[{#KEY}]',
					'formCheck' => true,
					'dbCheck' => true,
					'remove' => true]
			],
			// #44 List of all item types
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'Zabbix agent',
					'name' => 'Zabbix agent',
					'key' => 'item-zabbix-agent[{#KEY}]',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #45 Update and custom intervals are hidden if item key is mqtt.get
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'Zabbix agent (active)',
					'name' => 'Zabbix agent (active) mqtt',
					'key' => 'mqtt.get[{#KEY}]',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #46
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'Zabbix agent (active)',
					'name' => 'Zabbix agent (active)',
					'key' => 'item-zabbix-agent-active[{#KEY}]',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #47
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'Simple check',
					'name' => 'Simple check',
					'key' => 'item-simple-check[{#KEY}]',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #48
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'SNMP agent',
					'name' => 'SNMP agent',
					'key' => 'item-snmp-agent[{#KEY}]',
					'snmp_oid' => '[IF-MIB::]ifInOctets.1',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #49
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'SNMP trap',
					'name' => 'SNMP trap',
					'key' => 'snmptrap.fallback[{#KEY}]',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #50
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'Zabbix internal',
					'name' => 'Zabbix internal',
					'key' => 'item-zabbix-internal[{#KEY}]',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #51
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'Zabbix trapper',
					'name' => 'Zabbix trapper',
					'key' => 'item-zabbix-trapper[{#KEY}]',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #52
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'Zabbix trapper',
					'name' => 'Zabbix trapper with macro in allowed hosts field',
					'key' => 'item-zabbix-trapper-macro[{#KEY}]',
					'allowed_hosts' => '{$TEST}',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #53
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'Zabbix trapper',
					'name' => 'Zabbix trapper with macro and ip in allowed hosts field',
					'key' => 'item-zabbix-trapper-macro-ip[{#KEY}]',
					'allowed_hosts' => '{$MACRO},127.0.0.1',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #54
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'External check',
					'name' => 'External check',
					'key' => 'item-external-check[{#KEY}]',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #55
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'Database monitor',
					'name' => 'Database monitor',
					'key' => 'item-database-monitor[{#KEY}]',
					'params_ap' => 'SELECT * FROM items',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #56
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'IPMI agent',
					'name' => 'IPMI agent',
					'key' => 'item-ipmi-agent[{#KEY}]',
					'ipmi_sensor' => 'ipmi_sensor',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #57
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'IPMI agent',
					'name' => 'IPMI agent with spaces',
					'key' => 'item-ipmi-agent-spaces[{#KEY}]',
					'ipmi_sensor' => '   ipmi_sensor   ',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #58
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'SSH agent',
					'name' => 'SSH agent',
					'key' => 'item-ssh-agent[{#KEY}]',
					'username' => 'zabbix',
					'params_es' => 'executed script',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #59
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'TELNET agent',
					'name' => 'TELNET agent',
					'key' => 'item-telnet-agent[{#KEY}]',
					'username' => 'zabbix',
					'params_es' => 'executed script',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #60
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'Script',
					'name' => 'Script item',
					'key' => 'script.item[{#KEY}]',
					'script' => 'zabbix',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #61
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'Browser',
					'name' => 'Default browser item',
					'key' => 'default.browser.item[{#KEY}]',
					'dbCheck' => true,
					'formCheck' => true
				]
			],
			// #62
			[
				[
					'expected' => TEST_BAD,
					'type' => 'Script',
					'name' => 'Empty script',
					'key' => 'empty.script[{#KEY}]',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/params": cannot be empty.'
					]
				]
			],
			// #63
			[
				[
					'expected' => TEST_BAD,
					'type' => 'Browser',
					'name' => 'Browser item - empty script',
					'key' => 'empty.script.browser.item[{#KEY}]',
					'script' => '',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/params": cannot be empty.'
					]
				]
			],
			// #64
			[
				[
					'expected' => TEST_BAD,
					'type' => 'Script',
					'name' => 'Empty parameter name - script item',
					'key' => 'empty.parameter.script.item[{#KEY}]',
					'script' => 'script',
					'params_value' => 'value',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/parameters/1/name": cannot be empty.'
					]
				]
			],
			// #65
			[
				[
					'expected' => TEST_BAD,
					'type' => 'Browser',
					'name' => 'Empty parameter name - browser item',
					'key' => 'empty.param.name.browser.item[{#KEY}]',
					'params_value' => 'value',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/parameters/1/name": cannot be empty.'
					]
				]
			],
			// #66
			[
				[
					'expected' => TEST_BAD,
					'type' => 'IPMI agent',
					'name' => 'IPMI agent error',
					'key' => 'item-ipmi-agent-error[{#KEY}]',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/ipmi_sensor": cannot be empty.'
					]
				]
			],
			// #67
			[
				[
					'expected' => TEST_BAD,
					'type' => 'SSH agent',
					'name' => 'SSH agent error',
					'key' => 'item-ssh-agent-error[{#KEY}]',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/username": cannot be empty.'
					]
				]
			],
			// #68
			[
				[
					'expected' => TEST_BAD,
					'type' => 'TELNET agent',
					'name' => 'TELNET agent error',
					'key' => 'item-telnet-agent-error[{#KEY}]',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/username": cannot be empty.'
					]
				]
			],
			// #69
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'JMX agent',
					'name' => 'JMX agent',
					'key' => 'proto-jmx-agent[{#KEY}]',
					'dbCheck' => true,
					'formCheck' => true,
					'remove' => true
				]
			],
			// #70
			[
				[
					'expected' => TEST_GOOD,
					'type' => 'Calculated',
					'name' => 'Calculated',
					'key' => 'item-calculated[{#KEY}]',
					'params_f' => '"formula"',
					'dbCheck' => true,
					'formCheck' => true,
					'remove' => true
				]
			],
			// #71
			[
				[
					'expected' => TEST_BAD,
					'type' => 'Calculated',
					'name' => 'Calculated',
					'key' => 'item-calculated[{#KEY}]',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Invalid parameter "/1/params": cannot be empty.'
					]
				]
			],
			// #72 Empty SQL query
			[
				[
					'expected' => TEST_BAD,
					'type' => 'Database monitor',
					'name' => 'Database monitor',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Check the key, please. Default example was passed.'
					]
				]
			],
			// #73 Default
			[
				[
					'expected' => TEST_BAD,
					'type' => 'Database monitor',
					'name' => 'Database monitor',
					'params_ap' => 'SELECT * FROM items',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Check the key, please. Default example was passed.'
					]
				]
			],
			// #74 Default
			[
				[
					'expected' => TEST_BAD,
					'type' => 'SSH agent',
					'name' => 'SSH agent',
					'username' => 'zabbix',
					'params_es' => 'script to be executed',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Check the key, please. Default example was passed.'
					]
				]
			],
			// #75 Default
			[
				[
					'expected' => TEST_BAD,
					'type' => 'TELNET agent',
					'name' => 'TELNET agent',
					'username' => 'zabbix',
					'params_es' => 'script to be executed',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Check the key, please. Default example was passed.'
					]
				]
			],
			// #76 Default
			[
				[
					'expected' => TEST_BAD,
					'type' => 'JMX agent',
					'name' => 'JMX agent',
					'username' => 'zabbix',
					'error_msg' => 'Cannot add item prototype',
					'errors' => [
						'Incorrect value for field "key": cannot be empty.'
					]
				]
			]
		];
	}

	/**
	 * @dataProvider create
	 */
	public function testFormItemPrototype_SimpleCreate($data) {
		$this->page->login()->open('zabbix.php?action=item.prototype.list&parent_discoveryid=133800&context=host');

		if (isset($data['name'])) {
			$itemName = $data['name'];
		}
		if (isset($data['key'])) {
			$keyName = $data['key'];
		}

		$this->zbxTestContentControlButtonClickTextWait('Create item prototype');
		$dialog = COverlayDialogElement::find()->one()->waitUntilReady();
		$form = $dialog->asForm();
		$dialog_footer = $dialog->getFooter();

		if (isset($data['type'])) {
			$type = $data['type'];
			$type_value = $this->zbxTestGetValue("//z-select[@id='type']//li[text()='".$type."']");
			$this->zbxTestDropdownSelect('type', $type);
			$this->zbxTestAssertElementValue('type', $type_value);
		}
		else {
			$type = $this->zbxTestGetSelectedLabel('type');
		}

		if (isset($data['name'])) {
			$this->zbxTestInputTypeWait('name', $data['name']);
			if ($data['name'] != $this->zbxTestGetValue("//input[@id='name']")) {
				$this->zbxTestInputTypeOverwrite('name', $data['name']);
			}
			$this->zbxTestAssertElementValue('name', $data['name']);
		}
		$name = $this->zbxTestGetValue("//input[@id='name']");

		if (isset($data['key'])) {
			$this->zbxTestInputTypeOverwrite('key', $data['key']);
			if ($data['key'] != $this->zbxTestGetValue("//input[@id='key']")) {
				$this->zbxTestInputTypeOverwrite('key', $data['key']);
			}
			$this->zbxTestAssertElementValue('key', $data['key']);
		}
		$key = $this->zbxTestGetValue("//input[@id='key']");

		if (isset($data['username'])) {
			$this->zbxTestInputType('username', $data['username']);
		}

		if (isset($data['ipmi_sensor'])) {
				$this->zbxTestInputType('ipmi_sensor', $data['ipmi_sensor']);
				$ipmi_sensor = $this->zbxTestGetValue("//input[@id='ipmi_sensor']");
		}

		if (isset($data['script'])) {
			$form->getField('Script')->fill($data['script']);
		}

		if (isset($data['params_value'])) {
			$form->getField('name:parameters[0][value]')->fill($data['params_value']);
		}

		if (isset($data['allowed_hosts'])) {
			$this->zbxTestInputType('trapper_hosts', $data['allowed_hosts']);
		}

		if (isset($data['params_ap'])) {
			$this->zbxTestTextPresent('SQL query');
			$this->zbxTestInputTypeOverwrite('params_ap', $data['params_ap']);
		}

		if (isset($data['params_es'])) {
			$this->zbxTestInputTypeWait('params_es', $data['params_es']);
		}

		if (isset($data['params_f'])) {
			$this->zbxTestInputTypeWait('params_f', $data['params_f']);
		}

		if (isset($data['delay']))	{
			$this->zbxTestInputTypeOverwrite('delay', $data['delay']);
		}

		if (array_key_exists('snmp_oid', $data))	{
			$this->zbxTestInputTypeOverwrite('snmp_oid', $data['snmp_oid']);
		}

		// Check hidden update and custom interval for mqtt.get key.
		if (CTestArrayHelper::get($data, 'type') === 'Zabbix agent (active)'
				&& substr(CTestArrayHelper::get($data, 'key'), 0, 8) === 'mqtt.get') {
			$this->zbxTestTextNotVisible('Update interval');
			$this->zbxTestAssertNotVisibleId('js-item-delay-label');
			$this->zbxTestAssertNotVisibleId('js-item-delay-field');
			$this->zbxTestTextNotVisible('Custom intervals');
			$this->zbxTestAssertNotVisibleId('js-item-flex-intervals-label');
			$this->zbxTestAssertNotVisibleId('js-item-flex-intervals-field');
		}

		$itemFlexFlag = true;
		if (isset($data['flexPeriod'])) {

			$itemCount = 0;
			foreach ($data['flexPeriod'] as $period) {
				$this->zbxTestInputType('delay_flex_'.$itemCount.'_period', $period['flexTime']);

				if (isset($period['flexDelay'])) {
					$this->zbxTestInputTypeOverwrite('delay_flex_'.$itemCount.'_delay', $period['flexDelay']);
				}
				$itemCount ++;
				$form->query("xpath://div[@id='js-item-flex-intervals-field']//button[@class='btn-link element-table-add']")
					->one()->click();

				$this->zbxTestAssertVisibleId('delay_flex_'.$itemCount.'_delay');
				$this->zbxTestAssertVisibleId('delay_flex_'.$itemCount.'_period');

				if (isset($period['remove'])) {
					$form->query("xpath://table[@id='delay-flex-table']/tbody/tr[1]/td[4]/button")->one()
						->click();
				}
			}
		}

		if (isset($data['history'])) {
			$this->zbxTestInputTypeOverwrite('history', $data['history']);
		}

		if (isset($data['trends'])) {
			$this->zbxTestInputTypeOverwrite('trends', $data['trends']);
		}

		switch ($type) {
			case 'Zabbix agent':
			case 'Simple check':
			case 'SNMP agent':
			case 'SNMP trap':
			case 'External check':
			case 'IPMI agent':
			case 'SSH agent':
			case 'TELNET agent':
			case 'JMX agent':
				$interfaceid = $this->zbxTestGetText('//z-select[@id="interface-select"]//li[not(@disabled)]');
				break;
			default:
				$this->zbxTestAssertNotVisibleId('interface-select');
		}

		$value_type = $this->zbxTestGetSelectedLabel('value_type');

		if ($itemFlexFlag == true) {
			$dialog->getFooter()->query('button:Add')->one()->click();
			$expected = $data['expected'];
			switch ($expected) {
				case TEST_GOOD:
					$this->zbxTestCheckTitle('Configuration of item prototypes');
					$this->zbxTestWaitUntilMessageTextPresent('msg-good', 'Item prototype added');
					$this->zbxTestTextPresent($this->discoveryRule);
					break;

				case TEST_BAD:
					$this->zbxTestCheckTitle('Configuration of item prototypes');
					$this->assertMessage(TEST_BAD, $data['error_msg'], $data['errors']);
					$this->zbxTestTextPresent(['Name', 'Type', 'Key']);

					if (isset($data['formula'])) {
						$this->zbxTestAssertElementValue('formula', $data['formulaValue']);
					}

					$dialog->close();
					break;
			}
		}

		if (isset($data['formCheck'])) {
			$this->zbxTestOpen(self::HOST_LIST_PAGE);
			$this->filterEntriesAndOpenDiscovery($this->host);
			$this->zbxTestClickLinkTextWait($this->discoveryRule);
			$this->zbxTestClickLinkTextWait('Item prototypes');
			$this->zbxTestCheckHeader('Item prototypes');

			if (isset ($data['dbName'])) {
				$itemNameDB = $data['dbName'];
				$this->zbxTestTextPresent($itemNameDB);
				$this->zbxTestClickLinkTextWait($itemNameDB);
			}
			else {
				$this->zbxTestClickLinkTextWait($itemName);
			}

			$dialog_check = COverlayDialogElement::find()->one()->waitUntilReady();
			$check_form = $dialog_check->asForm();
			$this->assertEquals($itemName, $check_form->getField('Name')->getValue());
			$this->assertEquals($keyName, $check_form->getField('Key')->getValue());
			$this->zbxTestWaitUntilElementVisible(WebDriverBy::id('name'));
			$this->zbxTestAssertElementPresentXpath("//z-select[@id='type']//li[text()='$type']");

			switch ($type) {
				case 'Zabbix agent':
				case 'Simple check':
				case 'SNMP agent':
				case 'SNMP trap':
				case 'External check':
				case 'IPMI agent':
				case 'SSH agent':
				case 'TELNET agent':
				case 'JMX agent':
					$this->zbxTestAssertElementPresentXpath('//z-select[@id="interface-select"]//li[text()="'.$interfaceid.'"]');
					break;
				case 'Zabbix agent (active)':
					$this->zbxTestAssertNotVisibleId('interfaceid');
					// Check hidden update and custom interval for mqtt.get key.
					if (substr(CTestArrayHelper::get($data, 'key'), 0, 8) === 'mqtt.get') {
						$this->zbxTestTextNotVisible('Update interval');
						$this->zbxTestAssertNotVisibleId('js-item-delay-label');
						$this->zbxTestAssertNotVisibleId('js-item-delay-field');
						$this->zbxTestTextNotVisible('Custom intervals');
						$this->zbxTestAssertNotVisibleId('js-item-flex-intervals-label');
						$this->zbxTestAssertNotVisibleId('js-item-flex-intervals-field');
					}
					else {
						$this->zbxTestTextVisible('Update interval');
						$this->zbxTestAssertVisibleId('js-item-delay-label');
						$this->zbxTestAssertVisibleId('js-item-delay-field');
						$this->zbxTestTextVisible('Custom intervals');
						$this->zbxTestAssertVisibleId('js-item-flex-intervals-label');
						$this->zbxTestAssertVisibleId('js-item-flex-intervals-field');
					}
					break;
				default:
					$this->zbxTestAssertNotVisibleId('interface-select');
			}
			$this->zbxTestAssertElementPresentXpath("//z-select[@id='value_type']//li[text()='$value_type']");

			if (isset($data['ipmi_sensor'])) {
				$ipmiValue = $this->zbxTestGetValue("//input[@id='ipmi_sensor']");
				$this->assertEquals($ipmi_sensor, $ipmiValue);
			}

			$dialog_check->close();
		}

		if (isset($data['dbCheck'])) {
			$result = DBselect("SELECT name, key_ FROM items where name = '".$itemName."'  AND hostid = ".$this->hostid);

			while ($row = DBfetch($result)) {
				$this->assertEquals($row['name'], $itemName);
				$this->assertEquals($row['key_'], $keyName);
			}
		}

		if (isset($data['remove'])) {
			$result = DBselect("SELECT name, key_, itemid FROM items where name = '".$itemName."'  AND hostid = ".$this->hostid);
			while ($row = DBfetch($result)) {
				$itemId = $row['itemid'];
			}

			$this->zbxTestOpen(self::HOST_LIST_PAGE);
			$this->filterEntriesAndOpenDiscovery($this->host);
			$this->zbxTestClickLinkTextWait($this->discoveryRule);
			$this->zbxTestClickLinkTextWait('Item prototypes');

			$this->zbxTestCheckboxSelect("itemids_$itemId");
			$this->query('button:Delete')->one()->click();

			$this->zbxTestAcceptAlert();
			$this->zbxTestWaitUntilMessageTextPresent('msg-good', 'Item prototype deleted');
		}
	}

	/**
	 * Function for filtering necessary hosts and opening its Discovery rules.
	 *
	 * @param string    $name    name of a host
	 */
	private function filterEntriesAndOpenDiscovery($name) {
		$form = $this->query('name:zbx_filter')->asForm()->waitUntilReady()->one();
		$form->fill(['Name' => $name]);
		$this->query('button:Apply')->one()->waitUntilClickable()->click();
		$this->query('xpath://table[@class="list-table"]')->asTable()->one()->findRow('Name', $name)
				->getColumn('Discovery')->query('link:Discovery')->one()->click();
	}
}
