{"id":342172,"date":"2022-12-06T04:29:47","date_gmt":"2022-12-06T04:29:47","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=342172"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=342172","title":{"rendered":"<span>Geb Framework \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u043e\u0432<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/848\/078\/18d\/84807818d239d396c879c9bf8b770047.png\" width=\"780\" height=\"439\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/848\/078\/18d\/84807818d239d396c879c9bf8b770047.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c, \u043a\u043e\u043b\u043b\u0435\u0433\u0438. \u041e\u0434\u0438\u043d \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445 \u0438 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u043e\u0432 &#8212; \u044d\u0442\u043e Selenium. \u0423 \u044d\u0442\u043e\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u043b\u044e\u0441\u043e\u0432 \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439, \u043d\u043e \u0432 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0435\u0441\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0442\u0435\u0441\u0442\u043e\u0432. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u044e\u0442 Selenium.<\/p>\n<p>\u041e\u0434\u0438\u043d \u0438\u0437 \u0442\u0430\u043a\u0438\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 &#8212; Geb Framework, \u043e\u043d \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 Groovy \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 groovy DSL \u043d\u0430 \u043f\u043e\u043b\u043d\u0443\u044e \u043c\u043e\u0449\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043a \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044e Geb \u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043d\u0438\u043c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0441\u0432\u0435\u0436\u0438\u0442\u044c \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0442\u0435\u043c\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 Groovy:<\/p>\n<ul>\n<li>\n<p>\u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u0439 Groovy \u0438 \u043b\u044f\u043c\u0431\u0434 Java;<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u043c\u0435\u0442\u0430\u043a\u043b\u0430\u0441\u0441\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0441\u0431\u043e\u0440\u043a\u0438 Gradle;<\/p>\n<\/li>\n<li>\n<p>\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Spock;<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 \u043e\u0441\u043d\u043e\u0432\u0435 Geb \u043b\u0435\u0436\u0438\u0442 Spock.<\/p>\n<p>Spock \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 JUnit \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0443\u0434\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439 \u0438 \u201c\u043f\u043b\u044e\u0448\u0435\u043a\u201d.:<\/p>\n<ul>\n<li>\n<p>\u0412\u0435\u0431-\u043a\u043e\u043d\u0441\u043e\u043b\u044c (deprecated): <a href=\"https:\/\/github.com\/spockframework\/spockwebconsole\"><u>https:\/\/github.com\/spockframework\/spockwebconsole<\/u><\/a>\u00a0<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b: <a href=\"https:\/\/github.com\/spockframework\/spock-example\"><u>https:\/\/github.com\/spockframework\/spock-example<\/u><\/a>\u00a0<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u043b\u0430\u0434\u044b: <a href=\"https:\/\/github.com\/spockframework\/spock-gr8conf-2019%5C\"><u>https:\/\/github.com\/spockframework\/spock-gr8conf-2019\\<\/u><\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u0421 Geb \u043c\u043e\u0436\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0430\u0439\u0442\u0435: <a href=\"https:\/\/www.gebish.org\/manual\/current\/#introduction\"><u>https:\/\/www.gebish.org\/manual\/current\/#introduction<\/u><\/a><\/p>\n<p>Geb \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 <a href=\"https:\/\/github.com\/SeleniumHQ\/selenium\">Selenium Web Driver<\/a>.<\/p>\n<p>\u041a\u0430\u043a \u0441 \u043d\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c:<\/p>\n<p>\u0412\u044b\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0446\u0435\u043f\u043e\u0447\u043a\u0430 \u0438\u0437 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432:<\/p>\n<p><code>*SpockSpec -> Browser.drive -> *Page -> *Module<\/code><\/p>\n<p><em>SpockSpec<\/em> &#8212; \u043a\u043b\u0430\u0441\u0441\u044b \u0442\u0435\u0441\u0442\u043e\u0432, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 Spock.<\/p>\n<p><em>Page<\/em> \u0438 <em>Module<\/em> &#8212; \u0434\u043e\u043c\u0435\u043d\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b, \u043c\u043e\u0433\u0443\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 Navigator.<\/p>\n<p>\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/www.gebish.org\/manual\/current\/\"><u>https:\/\/www.gebish.org\/manual\/current\/<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.gebish.org\/\"><u>https:\/\/www.gebish.org\/<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/geb\/geb-example-maven\"><u>https:\/\/github.com\/geb\/geb-example-maven<\/u><\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 Selenium \u0438 \u0442\u0430\u043a\u0436\u0435 \u0441 Geb &#8212; \u044d\u0442\u043e <strong>Page Object: <\/strong><a href=\"https:\/\/github.com\/SeleniumHQ\/selenium\/wiki\/PageObjects\"><u>https:\/\/github.com\/SeleniumHQ\/selenium\/wiki\/PageObjects<\/u><\/a>.<\/p>\n<p>\u0412 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0432\u0430\u0448\u0435\u0433\u043e \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0435\u0441\u0442\u044c \u043e\u0431\u043b\u0430\u0441\u0442\u0438, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0432\u0430\u0448\u0438 \u0442\u0435\u0441\u0442\u044b. \u041e\u0431\u044a\u0435\u043a\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b (Page Object) \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u0443\u0435\u0442 \u0438\u0445 \u043a\u0430\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043a\u043e\u0434\u0435. \u042d\u0442\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0438 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435.<\/p>\n<h4>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0432\u044b\u0431\u043e\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445:<\/h4>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 Page Object, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u0432\u0435\u0431-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.<\/p>\n<p>\u0414\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f <strong>\u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b <\/strong>(\u043f\u0440\u0438\u0432\u0435\u0442, jquery).<\/p>\n<p><code>$(\u00abcss selector\u00bb, \u00abindex or range\u00bb, \u00abattribute \/ text matchers\u00bb)<\/code><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><em>$(&#171;div&#187;)\u00a0<\/em><\/p>\n<\/td>\n<td>\n<p align=\"left\"><em>\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 &#171;div&#187; \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435<\/em><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><em>$(&#171;div&#187;, 0)\u00a0<\/em><\/p>\n<\/td>\n<td>\n<p align=\"left\"><em>\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439\u00a0 &#171;div&#187; \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435<\/em><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><em>$(&#171;div&#187;, title: &#171;section&#187;)\u00a0<\/em><\/p>\n<\/td>\n<td>\n<p align=\"left\"><em>\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 &#171;div&#187;\u00a0 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 tittle = &#171;section&#187;.<\/em><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><em>$(&#171;div&#187;, 0, title: &#171;section&#187;)\u00a0<\/em><\/p>\n<\/td>\n<td>\n<p align=\"left\"><em>\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439 &#171;div&#187; \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 title\u00a0 &#171;section&#187;.<\/em><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><em>$(&#171;div.main&#187;)\u00a0<\/em><\/p>\n<\/td>\n<td>\n<p align=\"left\"><em>\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 &#171;div&#187; \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u044e\u0442 \u043a\u043b\u0430\u0441\u0441\u00a0 &#171;main&#187;.<\/em><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><em>$(&#171;div.main&#187;, 0)<\/em><\/p>\n<\/td>\n<td>\n<p align=\"left\"><em>\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439 &#171;div&#187;\u00a0 \u0441 \u043a\u043b\u0430\u0441\u0441\u043e\u043c &#171;main&#187;.<\/em><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <strong>By <\/strong>\u0438\u0437 <strong>WebDriver<\/strong>:<\/p>\n<pre><code class=\"java\">$(By.id(\"some-id\")) $(By.className(\"some-class\")) $(By.xpath('\/\/p[@class=\"xpath\"]'))<\/code><\/pre>\n<p><strong>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u0432\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445:<\/strong><\/p>\n<ol>\n<li>\n<p>Inline (\u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043e\u0434\u0435 \u0442\u0435\u0441\u0442\u043e\u0432)<\/p>\n<\/li>\n<li>\n<p>\u0421 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Page Object<\/p>\n<\/li>\n<\/ol>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u044b:<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Inline:<\/p>\n<pre><code class=\"java\">import geb.Browser     Browser.drive {         go \"http:\/\/gebish.org\"          assert title == \"Geb - Very Groovy Browser Automation\"          $(\"div.menu a.manuals\").click()         waitFor { !$(\"#manuals-menu\").hasClass(\"animating\") }          $(\"#manuals-menu a\")[0].click()          assert title.startsWith(\"The Book Of Geb\")     }<\/code><\/pre>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u043c Page Object:<\/p>\n<pre><code class=\"java\">import geb.Module import geb.Page  class ManualsMenuModule extends Module {     static content = {         toggle { $(\"div.menu a.manuals\") }         linksContainer { $(\"#manuals-menu\") }         links { linksContainer.find(\"a\") }     }      void open() {         toggle.click()         waitFor { !linksContainer.hasClass(\"animating\") }     } }<\/code><\/pre>\n<pre><code class=\"java\">import geb.Page import modules.ManualsMenuModule  class GebHomePage extends Page {     static url = \"http:\/\/gebish.org\"      static at = { title == \"Geb - Very Groovy Browser Automation\" }      static content = {         manualsMenu { module(ManualsMenuModule) }     } }<\/code><\/pre>\n<pre><code class=\"java\">class TheBookOfGebPage extends Page {     static at = { title.startsWith(\"The Book Of Geb\") } }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0442\u0435\u0441\u0442 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Page Object-\u043e\u0432.<\/p>\n<pre><code class=\"java\">import geb.Browser  Browser.drive {     to GebHomePage      manualsMenu.open()      manualsMenu.links[0].click()      at TheBookOfGebPage }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f? \u0418\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 Spock!<\/p>\n<pre><code class=\"java\">import geb.spock.GebSpec  class GebHomepageSpec extends GebSpec {      def \"can access The Book of Geb via homepage\"() {         given:         to GebHomePage          when:         manualsMenu.open()         manualsMenu.links[0].click()          then:         at TheBookOfGebPage     }  }<\/code><\/pre>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u0434 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e.<\/p>\n<p>\u0421\u0430\u043c\u0430\u044f \u043c\u0430\u043b\u0430\u044f \u0447\u0430\u0441\u0442\u044c &#8212; \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b \u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430.<\/p>\n<p><strong>Browser:<\/strong>\u00a0<\/p>\n<pre><code class=\"java\">Browser.drive {     go \"signup\"     assert $(\"h1\").text() == \"Signup Page\" }<\/code><\/pre>\n<p>baseUrl &#8212; \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 Browser.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<pre><code class=\"java\">Browser.drive {     go()       go \"signup\"       go \"signup\", param1: \"value1\", param2: \"value2\"  }<\/code><\/pre>\n<p>\u0427\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0435 \u043a\u043e\u0434\u0430?<\/p>\n<ul>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430\u00a0 base URL.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430\u00a0 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 URL \u043e\u0442\u00a0 base URL<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430\u00a0 URL \u0441 \u043d\u0443\u0436\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438: http:\/\/localhost\/signup?param1=value1&amp;param2=value2<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u043e\u043a\u043d\u0430\u043c\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430:<\/p>\n<pre><code class=\"java\">Browser.drive {     go()     $(\"a\").click()     withWindow({ title == \"Geb - Very Groovy Browser Automation\" }) {         assert $(\".slogan\").text().startsWith(\"Very Groovy browser automation.\")     } }<\/code><\/pre>\n<p><strong>\u0412\u044b\u0431\u043e\u0440\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 (\u043a\u043b\u0430\u0441\u0441 Navigator):<\/strong><\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u043c\u0435\u044e\u0449\u0438\u0435\u0441\u044f \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 Navigator \u043c\u0435\u0442\u043e\u0434\u044b:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>Case Sensitive<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>Case Insensitive<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>Description<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>startsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iStartsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>contains<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iContains<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043b\u044e\u0431\u043e\u043c \u043c\u0435\u0441\u0442\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>endsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iEndsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>containsWord<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iContainsWord<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0435 \u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u043c, \u043b\u0438\u0431\u043e \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0438\u043b\u0438 \u043a\u043e\u043d\u0446\u043e\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>notStartsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iNotStartsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u041d\u0415 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>notContains<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iNotContains<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0438\u0433\u0434\u0435 \u041d\u0415 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>notEndsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iNotEndsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u041d\u0415 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>notContainsWord<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iNotContainsWord<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u041d\u0415 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0435 \u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u043c, \u043b\u0438\u0431\u043e \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0438\u043b\u0438 \u043a\u043e\u043d\u0446\u043e\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e Matcher:<\/p>\n<ul>\n<li>\n<p>allOf &#8212; \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0435\u0441\u043b\u0438 \u0432\u0441\u0435 matcher-\u044b \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442<\/p>\n<\/li>\n<li>\n<p>anyOf &#8212; \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d matcher \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u043e\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f:<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f Navigator. \u041b\u0443\u0447\u0448\u0438\u043c \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u043f\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0430\u0442\u044c, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f <a href=\"https:\/\/www.gebish.org\/manual\/current\/api\/geb\/navigator\/event\/NavigatorEventListener.html\"><u>NavigatorEventListener<\/u><\/a> \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.\u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u043b\u0443\u0448\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0430\u0432\u0438\u0433\u0430\u0442\u043e\u0440\u0430, \u0442\u043e\u0433\u0434\u0430 <a href=\"https:\/\/www.gebish.org\/manual\/current\/api\/geb\/navigator\/event\/NavigatorEventListenerSupport.html\"><u>NavigatorEventListenerSupport<\/u><\/a> \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u044c\u0441\u044f, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c\u0438 \u043f\u0443\u0441\u0442\u044b\u043c\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438 \u0432\u0441\u0435\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432\u00a0 <a href=\"https:\/\/www.gebish.org\/manual\/current\/api\/geb\/navigator\/event\/NavigatorEventListener.html\"><u>NavigatorEventListener<\/u><\/a>.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>import geb.Browser import geb.navigator.Navigator import geb.navigator.event.NavigatorEventListenerSupport  navigatorEventListener = new NavigatorEventListenerSupport() {     void afterClick(Browser browser, Navigator navigator) {         println \"${navigator*.tag()} was clicked\"     } }<\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432:<\/p>\n<pre><code>assert $($(\"p.a\"), $(\"p.b\"))*.text() == [\"1\", \"2\"]<\/code><\/pre>\n<p>\u0438\u043b\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 add():<\/p>\n<pre><code>assert $(\"p.a\").add(\"p.b\").add(By.className(\"c\"))*.text() == [\"1\", \"2\", \"3\"]<\/code><\/pre>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0432 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u0430\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439.<\/p>\n<h4>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/h4>\n<p><strong>\u041d\u0430\u0436\u0430\u0442\u0438\u0435 \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 (click())<\/strong>:<\/p>\n<p>\u0423 \u043a\u043b\u0430\u0441\u0441\u0430 Page \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432<strong> click()<\/strong>:<\/p>\n<pre><code>click(Class) , click(Page) and click(List)<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>$(\"a.login\").click(LoginPage)<\/code><\/pre>\n<p><strong>\u0424\u043e\u043a\u0443\u0441\u0438\u0440\u043e\u0432\u043a\u0430 (focused())<\/strong>:<\/p>\n<pre><code>$(name: \"description\").click()  assert focused().attr(\"name\") == \"description\" assert $(name: \"description\").focused<\/code><\/pre>\n<p><strong>\u0412\u0432\u043e\u0434 \u0442\u0435\u043a\u0441\u0442\u0430 (&lt;&lt;)<\/strong>:<\/p>\n<pre><code>$(\"input\") &lt;&lt; \"foo\" assert $(\"input\").value() == \"foo\"<\/code><\/pre>\n<p>\u0438\u043b\u0438 \u043d\u0435\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<pre><code>import org.openqa.selenium.Keys  $(\"input\") &lt;&lt; Keys.chord(Keys.CONTROL, \"c\")<\/code><\/pre>\n<p><strong>\u0412\u044b\u0431\u043e\u0440 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u0441\u043f\u0438\u0441\u043a\u0430\u0445:<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).artist = &#171;1&#187;\u00a0<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0435\u0440\u0432\u0430\u044f \u043e\u043f\u0446\u0438\u044f, \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u0430\u044f \u043f\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e\u00a0 \u0435\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).artist = 2\u00a0<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u0435\u0433\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0443 value \u0441 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u0442\u0438\u043f\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).artist = &#171;Alexander&#187;<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u0440\u0435\u0442\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0432\u044b\u0431\u0440\u0430\u043d \u043f\u043e \u0435\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0443.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0414\u043b\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u0441\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u0432\u044b\u0431\u043e\u0440\u043e\u043c:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).genres = [&#171;2&#187;, &#171;3&#187;]\u00a0<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0442\u043e\u0440\u043e\u0439 \u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0438\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).genres = [1, 4, 5]\u00a0<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0435\u0440\u0432\u0430\u044f, \u0447\u0435\u0442\u0432\u0435\u0440\u0442\u0430\u044f \u0438 \u043f\u044f\u0442\u0430\u044f \u043e\u043f\u0446\u0438\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0438\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).genres = [&#171;Alt folk&#187;, &#171;Hair metal&#187;]\u00a0<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0435\u0440\u0432\u044b\u0439 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0438\u0445 \u0442\u0435\u043a\u0441\u0442\u0443.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).genres = <strong>[]<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0441\u0435 \u043e\u043f\u0446\u0438\u0438 \u043d\u0430 \u0432\u044b\u0431\u043e\u0440.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><strong>\u0414\u043b\u044f \u0447\u0435\u043a\u0431\u043e\u043a\u0441\u043e\u0432:<\/strong><\/p>\n<pre><code>$(\"form\").pet = true<\/code><\/pre>\n<p>\u041c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440:<\/p>\n<pre><code>$(\"form\").pet = [\"dog\", \"lizard\"] $(\"form\").pet = [\"Canis familiaris\", \"Lacerta\"]<\/code><\/pre>\n<p><strong>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432:<\/strong><\/p>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f uploadedFile \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 File, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043d\u0430 \u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c. \u0412\u043e\u0442 \u0442\u0430\u043a \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b:<\/p>\n<pre><code>$(\"form\").csvFile = uploadedFile.absolutePath<\/code><\/pre>\n<p><strong>\u0421\u043b\u043e\u0436\u043d\u044b\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f (\u0441\u0435\u043a\u0446\u0438\u044f interact()):<\/strong><\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b:<\/p>\n<pre><code>interact {     keyDown Keys.SHIFT     click $(\"li.clicky\")     keyUp Keys.SHIFT }  interact {     clickAndHold($('#draggable'))     moveByOffset(150, 200)     release() }<\/code><\/pre>\n<p>\u0438\u043b\u0438<\/p>\n<pre><code>interact {     dragAndDropBy($(\"#draggable\"), 150, 200) }<\/code><\/pre>\n<h4>Content:<\/h4>\n<p>\u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 Page \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0435\u043a\u0446\u0438\u044e Content &#8212; \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.<\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 Content: <code>\u00abname\u00bb { \u00abdefinition\u00bb }<\/code><\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>&lt;div id=\"a\">a&lt;\/div> class PageWithDiv extends Page {     static content = {         theDiv { $('div', id: 'a') }     } }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c?<\/p>\n<ol>\n<li>\n<p>\u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0430 page<\/p>\n<\/li>\n<li>\n<p>\u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u043a \u043f\u043e\u043b\u044f\u043c<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>Browser.drive {     to PageWithDiv      \/\/ Following two lines are equivalent     assert theDiv.text() == \"a\"     assert theDiv().text() == \"a\" }  Browser.drive {     to PageWithDiv     assert page.theDiv.text() == \"a\" }<\/code><\/pre>\n<p>\u0428\u0430\u0431\u043b\u043e\u043d\u044b:<\/p>\n<pre><code>\u00abname\u00bb(\u00aboptions map\u00bb) { \u00abdefinition\u00bb }<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>theDiv(cache: false, required: false) { $(\"div\", id: \"a\") }<\/code><\/pre>\n<p>\u041a\u0430\u043a\u0438\u0435 \u0435\u0441\u0442\u044c \u043e\u043f\u0446\u0438\u0438?<\/p>\n<ul>\n<li>\n<p>required<\/p>\n<\/li>\n<li>\n<p>max, min<\/p>\n<\/li>\n<li>\n<p>cache<\/p>\n<\/li>\n<li>\n<p>to &#8212; option allows the definition of which page the browser will be sent to if the content is clicked<\/p>\n<\/li>\n<li>\n<p>wait &#8212; \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 (\u0432 \u0446\u0435\u043b\u043e\u043c \u0430\u043d\u0430\u043b\u043e\u0433 waitFor).<\/p>\n<\/li>\n<li>\n<p>page &#8212; \u0434\u043b\u044f \u0444\u0440\u0435\u0439\u043c\u043e\u0432<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b:<\/p>\n<pre><code>static content = {     loginButton(to: [LoginSuccessfulPage, LoginFailedPage]) { $(\"input.loginButton\") } }  class DynamicPageWithWaiting extends Page {     static content = {         dynamicallyAdded(wait: true) { $(\"p.dynamic\") }     } } class PageWithFrame extends Page {     static content = {         myFrame(page: FrameDescribingPage) { $('#frame-id') }     } }  class FrameDescribingPage extends Page {     static content = {         frameContentsText { $('span').text() }     }<\/code><\/pre>\n<h4>\u041c\u043e\u0434\u0443\u043b\u0438<\/h4>\n<p>\u041d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445 Page.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>class ParameterizedModule extends Module {     static content = {         button {             $(\"form\", id: formId).find(\"input\", type: \"button\")         }     }     String formId }<\/code><\/pre>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043c\u043e\u0434\u0443\u043b\u044f:<\/p>\n<pre><code>class ParameterizedModulePage extends Page {     static content = {         form { id -> module(new ParameterizedModule(formId: id)) }     } } Browser.drive {     to ParameterizedModulePage     form(\"personal-data\").button.click() }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 Page (\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b), Content-\u044b \u0438 \u043c\u043e\u0434\u0443\u043b\u0438, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u0433\u0438\u0431\u043a\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u044b. \u041d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u0438 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u044f\u0437\u044b\u043a\u0430 groovy \u043f\u0440\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 Geb.<\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u0430 \u0432 \u043f\u0440\u0435\u0434\u0434\u0432\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0440\u0442\u0430 \u043a\u0443\u0440\u0441\u0430 <a href=\"https:\/\/otus.pw\/gSJq\/\">Groovy Developer<\/a>. \u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0430\u0435\u043c \u0432\u0441\u0435\u0445 \u043d\u0430 <a href=\"https:\/\/otus.pw\/gSJq\/\">\u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 \u0443\u0440\u043e\u043a \u043a\u0443\u0440\u0441\u0430<\/a>, \u0433\u0434\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u044b \u0432 Jenkins: \u0438\u0437 \u043a\u0430\u043a\u0438\u0445 \u0448\u0430\u0433\u043e\u0432 \u0438 \u0431\u043b\u043e\u043a\u043e\u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u0442, \u043d\u0430\u0443\u0447\u0438\u043c\u0441\u044f \u043f\u0438\u0441\u0430\u0442\u044c groovy \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u043e\u0432, \u0438\u0437\u0443\u0447\u0438\u043c \u0438\u0445 \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438.<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/otus.pw\/gSJq\/\">\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 \u0443\u0440\u043e\u043a<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/otus\/blog\/703612\/\"> https:\/\/habr.com\/ru\/company\/otus\/blog\/703612\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c, \u043a\u043e\u043b\u043b\u0435\u0433\u0438. \u041e\u0434\u0438\u043d \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445 \u0438 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u043e\u0432 &#8212; \u044d\u0442\u043e Selenium. \u0423 \u044d\u0442\u043e\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u043b\u044e\u0441\u043e\u0432 \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439, \u043d\u043e \u0432 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0435\u0441\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0442\u0435\u0441\u0442\u043e\u0432. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u044e\u0442 Selenium.<\/p>\n<p>\u041e\u0434\u0438\u043d \u0438\u0437 \u0442\u0430\u043a\u0438\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 &#8212; Geb Framework, \u043e\u043d \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 Groovy \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 groovy DSL \u043d\u0430 \u043f\u043e\u043b\u043d\u0443\u044e \u043c\u043e\u0449\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043a \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044e Geb \u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043d\u0438\u043c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0441\u0432\u0435\u0436\u0438\u0442\u044c \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0442\u0435\u043c\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 Groovy:<\/p>\n<ul>\n<li>\n<p>\u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u0439 Groovy \u0438 \u043b\u044f\u043c\u0431\u0434 Java;<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u043c\u0435\u0442\u0430\u043a\u043b\u0430\u0441\u0441\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0441\u0431\u043e\u0440\u043a\u0438 Gradle;<\/p>\n<\/li>\n<li>\n<p>\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Spock;<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 \u043e\u0441\u043d\u043e\u0432\u0435 Geb \u043b\u0435\u0436\u0438\u0442 Spock.<\/p>\n<p>Spock \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 JUnit \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0443\u0434\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439 \u0438 \u201c\u043f\u043b\u044e\u0448\u0435\u043a\u201d.:<\/p>\n<ul>\n<li>\n<p>\u0412\u0435\u0431-\u043a\u043e\u043d\u0441\u043e\u043b\u044c (deprecated): <a href=\"https:\/\/github.com\/spockframework\/spockwebconsole\"><u>https:\/\/github.com\/spockframework\/spockwebconsole<\/u><\/a>\u00a0<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b: <a href=\"https:\/\/github.com\/spockframework\/spock-example\"><u>https:\/\/github.com\/spockframework\/spock-example<\/u><\/a>\u00a0<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u043b\u0430\u0434\u044b: <a href=\"https:\/\/github.com\/spockframework\/spock-gr8conf-2019%5C\"><u>https:\/\/github.com\/spockframework\/spock-gr8conf-2019\\<\/u><\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u0421 Geb \u043c\u043e\u0436\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0430\u0439\u0442\u0435: <a href=\"https:\/\/www.gebish.org\/manual\/current\/#introduction\"><u>https:\/\/www.gebish.org\/manual\/current\/#introduction<\/u><\/a><\/p>\n<p>Geb \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 <a href=\"https:\/\/github.com\/SeleniumHQ\/selenium\">Selenium Web Driver<\/a>.<\/p>\n<p>\u041a\u0430\u043a \u0441 \u043d\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c:<\/p>\n<p>\u0412\u044b\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0446\u0435\u043f\u043e\u0447\u043a\u0430 \u0438\u0437 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432:<\/p>\n<p><code>*SpockSpec -> Browser.drive -> *Page -> *Module<\/code><\/p>\n<p><em>SpockSpec<\/em> &#8212; \u043a\u043b\u0430\u0441\u0441\u044b \u0442\u0435\u0441\u0442\u043e\u0432, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 Spock.<\/p>\n<p><em>Page<\/em> \u0438 <em>Module<\/em> &#8212; \u0434\u043e\u043c\u0435\u043d\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b, \u043c\u043e\u0433\u0443\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 Navigator.<\/p>\n<p>\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/www.gebish.org\/manual\/current\/\"><u>https:\/\/www.gebish.org\/manual\/current\/<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.gebish.org\/\"><u>https:\/\/www.gebish.org\/<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/geb\/geb-example-maven\"><u>https:\/\/github.com\/geb\/geb-example-maven<\/u><\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 Selenium \u0438 \u0442\u0430\u043a\u0436\u0435 \u0441 Geb &#8212; \u044d\u0442\u043e <strong>Page Object: <\/strong><a href=\"https:\/\/github.com\/SeleniumHQ\/selenium\/wiki\/PageObjects\"><u>https:\/\/github.com\/SeleniumHQ\/selenium\/wiki\/PageObjects<\/u><\/a>.<\/p>\n<p>\u0412 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0432\u0430\u0448\u0435\u0433\u043e \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0435\u0441\u0442\u044c \u043e\u0431\u043b\u0430\u0441\u0442\u0438, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0432\u0430\u0448\u0438 \u0442\u0435\u0441\u0442\u044b. \u041e\u0431\u044a\u0435\u043a\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b (Page Object) \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u0443\u0435\u0442 \u0438\u0445 \u043a\u0430\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043a\u043e\u0434\u0435. \u042d\u0442\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0438 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435.<\/p>\n<h4>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0432\u044b\u0431\u043e\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445:<\/h4>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 Page Object, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u0432\u0435\u0431-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.<\/p>\n<p>\u0414\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f <strong>\u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b <\/strong>(\u043f\u0440\u0438\u0432\u0435\u0442, jquery).<\/p>\n<p><code>$(\u00abcss selector\u00bb, \u00abindex or range\u00bb, \u00abattribute \/ text matchers\u00bb)<\/code><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><em>$(&#171;div&#187;)\u00a0<\/em><\/p>\n<\/td>\n<td>\n<p align=\"left\"><em>\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 &#171;div&#187; \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435<\/em><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><em>$(&#171;div&#187;, 0)\u00a0<\/em><\/p>\n<\/td>\n<td>\n<p align=\"left\"><em>\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439\u00a0 &#171;div&#187; \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435<\/em><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><em>$(&#171;div&#187;, title: &#171;section&#187;)\u00a0<\/em><\/p>\n<\/td>\n<td>\n<p align=\"left\"><em>\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 &#171;div&#187;\u00a0 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 tittle = &#171;section&#187;.<\/em><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><em>$(&#171;div&#187;, 0, title: &#171;section&#187;)\u00a0<\/em><\/p>\n<\/td>\n<td>\n<p align=\"left\"><em>\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439 &#171;div&#187; \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 title\u00a0 &#171;section&#187;.<\/em><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><em>$(&#171;div.main&#187;)\u00a0<\/em><\/p>\n<\/td>\n<td>\n<p align=\"left\"><em>\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 &#171;div&#187; \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u044e\u0442 \u043a\u043b\u0430\u0441\u0441\u00a0 &#171;main&#187;.<\/em><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><em>$(&#171;div.main&#187;, 0)<\/em><\/p>\n<\/td>\n<td>\n<p align=\"left\"><em>\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439 &#171;div&#187;\u00a0 \u0441 \u043a\u043b\u0430\u0441\u0441\u043e\u043c &#171;main&#187;.<\/em><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <strong>By <\/strong>\u0438\u0437 <strong>WebDriver<\/strong>:<\/p>\n<pre><code class=\"java\">$(By.id(\"some-id\")) $(By.className(\"some-class\")) $(By.xpath('\/\/p[@class=\"xpath\"]'))<\/code><\/pre>\n<p><strong>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u0432\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445:<\/strong><\/p>\n<ol>\n<li>\n<p>Inline (\u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043e\u0434\u0435 \u0442\u0435\u0441\u0442\u043e\u0432)<\/p>\n<\/li>\n<li>\n<p>\u0421 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Page Object<\/p>\n<\/li>\n<\/ol>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u044b:<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Inline:<\/p>\n<pre><code class=\"java\">import geb.Browser     Browser.drive {         go \"http:\/\/gebish.org\"          assert title == \"Geb - Very Groovy Browser Automation\"          $(\"div.menu a.manuals\").click()         waitFor { !$(\"#manuals-menu\").hasClass(\"animating\") }          $(\"#manuals-menu a\")[0].click()          assert title.startsWith(\"The Book Of Geb\")     }<\/code><\/pre>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u043c Page Object:<\/p>\n<pre><code class=\"java\">import geb.Module import geb.Page  class ManualsMenuModule extends Module {     static content = {         toggle { $(\"div.menu a.manuals\") }         linksContainer { $(\"#manuals-menu\") }         links { linksContainer.find(\"a\") }     }      void open() {         toggle.click()         waitFor { !linksContainer.hasClass(\"animating\") }     } }<\/code><\/pre>\n<pre><code class=\"java\">import geb.Page import modules.ManualsMenuModule  class GebHomePage extends Page {     static url = \"http:\/\/gebish.org\"      static at = { title == \"Geb - Very Groovy Browser Automation\" }      static content = {         manualsMenu { module(ManualsMenuModule) }     } }<\/code><\/pre>\n<pre><code class=\"java\">class TheBookOfGebPage extends Page {     static at = { title.startsWith(\"The Book Of Geb\") } }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0442\u0435\u0441\u0442 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Page Object-\u043e\u0432.<\/p>\n<pre><code class=\"java\">import geb.Browser  Browser.drive {     to GebHomePage      manualsMenu.open()      manualsMenu.links[0].click()      at TheBookOfGebPage }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f? \u0418\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 Spock!<\/p>\n<pre><code class=\"java\">import geb.spock.GebSpec  class GebHomepageSpec extends GebSpec {      def \"can access The Book of Geb via homepage\"() {         given:         to GebHomePage          when:         manualsMenu.open()         manualsMenu.links[0].click()          then:         at TheBookOfGebPage     }  }<\/code><\/pre>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u0434 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e.<\/p>\n<p>\u0421\u0430\u043c\u0430\u044f \u043c\u0430\u043b\u0430\u044f \u0447\u0430\u0441\u0442\u044c &#8212; \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b \u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430.<\/p>\n<p><strong>Browser:<\/strong>\u00a0<\/p>\n<pre><code class=\"java\">Browser.drive {     go \"signup\"     assert $(\"h1\").text() == \"Signup Page\" }<\/code><\/pre>\n<p>baseUrl &#8212; \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 Browser.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<pre><code class=\"java\">Browser.drive {     go()       go \"signup\"       go \"signup\", param1: \"value1\", param2: \"value2\"  }<\/code><\/pre>\n<p>\u0427\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0435 \u043a\u043e\u0434\u0430?<\/p>\n<ul>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430\u00a0 base URL.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430\u00a0 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 URL \u043e\u0442\u00a0 base URL<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430\u00a0 URL \u0441 \u043d\u0443\u0436\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438: http:\/\/localhost\/signup?param1=value1&amp;param2=value2<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u043e\u043a\u043d\u0430\u043c\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430:<\/p>\n<pre><code class=\"java\">Browser.drive {     go()     $(\"a\").click()     withWindow({ title == \"Geb - Very Groovy Browser Automation\" }) {         assert $(\".slogan\").text().startsWith(\"Very Groovy browser automation.\")     } }<\/code><\/pre>\n<p><strong>\u0412\u044b\u0431\u043e\u0440\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 (\u043a\u043b\u0430\u0441\u0441 Navigator):<\/strong><\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u043c\u0435\u044e\u0449\u0438\u0435\u0441\u044f \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 Navigator \u043c\u0435\u0442\u043e\u0434\u044b:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>Case Sensitive<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>Case Insensitive<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>Description<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>startsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iStartsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>contains<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iContains<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043b\u044e\u0431\u043e\u043c \u043c\u0435\u0441\u0442\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>endsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iEndsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>containsWord<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iContainsWord<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0435 \u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u043c, \u043b\u0438\u0431\u043e \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0438\u043b\u0438 \u043a\u043e\u043d\u0446\u043e\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>notStartsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iNotStartsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u041d\u0415 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>notContains<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iNotContains<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0438\u0433\u0434\u0435 \u041d\u0415 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>notEndsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iNotEndsWith<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u041d\u0415 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>notContainsWord<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>iNotContainsWord<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u041d\u0415 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0435 \u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u043c, \u043b\u0438\u0431\u043e \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0438\u043b\u0438 \u043a\u043e\u043d\u0446\u043e\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e Matcher:<\/p>\n<ul>\n<li>\n<p>allOf &#8212; \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0435\u0441\u043b\u0438 \u0432\u0441\u0435 matcher-\u044b \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442<\/p>\n<\/li>\n<li>\n<p>anyOf &#8212; \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d matcher \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u043e\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f:<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f Navigator. \u041b\u0443\u0447\u0448\u0438\u043c \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u043f\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0430\u0442\u044c, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f <a href=\"https:\/\/www.gebish.org\/manual\/current\/api\/geb\/navigator\/event\/NavigatorEventListener.html\"><u>NavigatorEventListener<\/u><\/a> \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.\u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u043b\u0443\u0448\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0430\u0432\u0438\u0433\u0430\u0442\u043e\u0440\u0430, \u0442\u043e\u0433\u0434\u0430 <a href=\"https:\/\/www.gebish.org\/manual\/current\/api\/geb\/navigator\/event\/NavigatorEventListenerSupport.html\"><u>NavigatorEventListenerSupport<\/u><\/a> \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u044c\u0441\u044f, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c\u0438 \u043f\u0443\u0441\u0442\u044b\u043c\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438 \u0432\u0441\u0435\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432\u00a0 <a href=\"https:\/\/www.gebish.org\/manual\/current\/api\/geb\/navigator\/event\/NavigatorEventListener.html\"><u>NavigatorEventListener<\/u><\/a>.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>import geb.Browser import geb.navigator.Navigator import geb.navigator.event.NavigatorEventListenerSupport  navigatorEventListener = new NavigatorEventListenerSupport() {     void afterClick(Browser browser, Navigator navigator) {         println \"${navigator*.tag()} was clicked\"     } }<\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432:<\/p>\n<pre><code>assert $($(\"p.a\"), $(\"p.b\"))*.text() == [\"1\", \"2\"]<\/code><\/pre>\n<p>\u0438\u043b\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 add():<\/p>\n<pre><code>assert $(\"p.a\").add(\"p.b\").add(By.className(\"c\"))*.text() == [\"1\", \"2\", \"3\"]<\/code><\/pre>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0432 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u0430\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439.<\/p>\n<h4>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/h4>\n<p><strong>\u041d\u0430\u0436\u0430\u0442\u0438\u0435 \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 (click())<\/strong>:<\/p>\n<p>\u0423 \u043a\u043b\u0430\u0441\u0441\u0430 Page \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432<strong> click()<\/strong>:<\/p>\n<pre><code>click(Class) , click(Page) and click(List)<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>$(\"a.login\").click(LoginPage)<\/code><\/pre>\n<p><strong>\u0424\u043e\u043a\u0443\u0441\u0438\u0440\u043e\u0432\u043a\u0430 (focused())<\/strong>:<\/p>\n<pre><code>$(name: \"description\").click()  assert focused().attr(\"name\") == \"description\" assert $(name: \"description\").focused<\/code><\/pre>\n<p><strong>\u0412\u0432\u043e\u0434 \u0442\u0435\u043a\u0441\u0442\u0430 (&lt;&lt;)<\/strong>:<\/p>\n<pre><code>$(\"input\") &lt;&lt; \"foo\" assert $(\"input\").value() == \"foo\"<\/code><\/pre>\n<p>\u0438\u043b\u0438 \u043d\u0435\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<pre><code>import org.openqa.selenium.Keys  $(\"input\") &lt;&lt; Keys.chord(Keys.CONTROL, \"c\")<\/code><\/pre>\n<p><strong>\u0412\u044b\u0431\u043e\u0440 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u0441\u043f\u0438\u0441\u043a\u0430\u0445:<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).artist = &#171;1&#187;\u00a0<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0435\u0440\u0432\u0430\u044f \u043e\u043f\u0446\u0438\u044f, \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u0430\u044f \u043f\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e\u00a0 \u0435\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).artist = 2\u00a0<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u0435\u0433\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0443 value \u0441 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u0442\u0438\u043f\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).artist = &#171;Alexander&#187;<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u0440\u0435\u0442\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0432\u044b\u0431\u0440\u0430\u043d \u043f\u043e \u0435\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0443.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0414\u043b\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u0441\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u0432\u044b\u0431\u043e\u0440\u043e\u043c:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).genres = [&#171;2&#187;, &#171;3&#187;]\u00a0<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0442\u043e\u0440\u043e\u0439 \u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0438\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).genres = [1, 4, 5]\u00a0<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0435\u0440\u0432\u0430\u044f, \u0447\u0435\u0442\u0432\u0435\u0440\u0442\u0430\u044f \u0438 \u043f\u044f\u0442\u0430\u044f \u043e\u043f\u0446\u0438\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0438\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).genres = [&#171;Alt folk&#187;, &#171;Hair metal&#187;]\u00a0<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0435\u0440\u0432\u044b\u0439 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0438\u0445 \u0442\u0435\u043a\u0441\u0442\u0443.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">$(&#171;form&#187;).genres = <strong>[]<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0441\u0435 \u043e\u043f\u0446\u0438\u0438 \u043d\u0430 \u0432\u044b\u0431\u043e\u0440.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><strong>\u0414\u043b\u044f \u0447\u0435\u043a\u0431\u043e\u043a\u0441\u043e\u0432:<\/strong><\/p>\n<pre><code>$(\"form\").pet = true<\/code><\/pre>\n<p>\u041c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440:<\/p>\n<pre><code>$(\"form\").pet = [\"dog\", \"lizard\"] $(\"form\").pet = [\"Canis familiaris\", \"Lacerta\"]<\/code><\/pre>\n<p><strong>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432:<\/strong><\/p>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f uploadedFile \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 File, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043d\u0430 \u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c. \u0412\u043e\u0442 \u0442\u0430\u043a \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b:<\/p>\n<pre><code>$(\"form\").csvFile = uploadedFile.absolutePath<\/code><\/pre>\n<p><strong>\u0421\u043b\u043e\u0436\u043d\u044b\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f (\u0441\u0435\u043a\u0446\u0438\u044f interact()):<\/strong><\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b:<\/p>\n<pre><code>interact {     keyDown Keys.SHIFT     click $(\"li.clicky\")     keyUp Keys.SHIFT }  interact {     clickAndHold($('#draggable'))     moveByOffset(150, 200)     release() }<\/code><\/pre>\n<p>\u0438\u043b\u0438<\/p>\n<pre><code>interact {     dragAndDropBy($(\"#draggable\"), 150, 200) }<\/code><\/pre>\n<h4>Content:<\/h4>\n<p>\u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 Page \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0435\u043a\u0446\u0438\u044e Content &#8212; \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.<\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 Content: <code>\u00abname\u00bb { \u00abdefinition\u00bb }<\/code><\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>&lt;div id=\"a\">a&lt;\/div> class PageWithDiv extends Page {     static content = {         theDiv { $('div', id: 'a') }     } }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c?<\/p>\n<ol>\n<li>\n<p>\u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0430 page<\/p>\n<\/li>\n<li>\n<p>\u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u043a \u043f\u043e\u043b\u044f\u043c<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>Browser.drive {     to PageWithDiv      \/\/ Following two lines are equivalent     assert theDiv.text() == \"a\"     assert theDiv().text() == \"a\" }  Browser.drive {     to PageWithDiv     assert page.theDiv.text() == \"a\" }<\/code><\/pre>\n<p>\u0428\u0430\u0431\u043b\u043e\u043d\u044b:<\/p>\n<pre><code>\u00abname\u00bb(\u00aboptions map\u00bb) { \u00abdefinition\u00bb }<\/code><\/pre>\n<p>\u041f\u0440<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-342172","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/342172","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=342172"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/342172\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=342172"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=342172"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=342172"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}