
рдкрд░рд┐рдЪрдп
рдлрд┐рд░ рд╕реЗ рдирдорд╕реНрдХрд╛рд░! рдореИрдВ рдЖрдкрдХреЛ рд╕реЗрд▓реЗрдирд┐рдпрдо рдФрд░ рд╕реА # рдореЗрдВ рд╡реЗрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдкрд░реАрдХреНрд╖рдг рдкрд░ рд▓реЗрдЦ рдХрд╛ рджреВрд╕рд░рд╛ рднрд╛рдЧ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реВрдВред рдФрд░ рдЕрдЧрд░ рдкрд╣рд▓рд╛ рднрд╛рдЧ "рдХрдкреНрддрд╛рди рд╕рдмреВрдд" рдХреА рд╢реНрд░реЗрдгреА рд╕реЗ рдерд╛, рдЬрд┐рд╕рд╕реЗ рдкрд╛рдардХреЛрдВ рдореЗрдВ рдирд╛рд░рд╛рдЬрдЧреА рдереА, рддреЛ рдЗрд╕ рд╣рд┐рд╕реНрд╕реЗ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХреЛрдб рд╣реЛрдВрдЧреЗред рдФрд░ рдЗрд╕рд▓рд┐рдП, рд╕реЗрд▓реЗрдирд┐рдпрдо рдПрдкреАрдЖрдИ рдкрд░ рдПрдХ рдЖрд╡рд░рдг рдХреНрдпреЛрдВ рд▓рд┐рдЦреЗрдВ? рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
- IWebDriver рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдкреНрд░рдмрдВрдзрди рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЕрд▓реНрдк рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рд╕рднреА рдХреЛ рдЦреБрдж рдХреЛ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛
- рддрддреНрд╡ рдХрд╛ рд╡рд░реНрдгрди рдПрдХ рд╕рд╛рде рдЗрд╕рдХреА рдЦреЛрдЬ рдХреЗ рд╕рд╛рде рд╣реЛрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддреНред рдЬрд┐рд╕ рд╕рдордп рддрддреНрд╡ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдпрд╣ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдореМрдЬреВрдж рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдкреНрд░рд╛рдпрдГ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдЧреЗрдЯрд░ рд▓рд┐рдЦрдХрд░ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдУрд╡рд░рдХрд┐рд▓ рдФрд░ рдЦрд░рд╛рдм рд╣реИ
- ISearchContext.FindElements рдХреЗрд╡рд▓ OpenQA.Selenium.By рдкреНрд░рдХрд╛рд░ рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рд╣рдо рдПрдХ рд╕рд╛рде рдХрдИ рдЧреБрдгреЛрдВ рдХреЛ рдирд╣реАрдВ рдЦреЛрдЬ рд╕рдХрддреЗред рдЖрдорддреМрд░ рдкрд░, рдПрдХ рддрддреНрд╡ рдХреЛ рдкрд╣рд▓реЗ рдорд╛рдирджрдВрдб рджреНрд╡рд╛рд░рд╛ рдЦреЛрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рд╕реНрдХреНрд░реАрдирд┐рдВрдЧ рдмрд╛рдХреА рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ
- рдХрдИ рд╕реНрдкрд╖реНрдЯ рддрд░реАрдХреЗ рдФрд░ рдЧреБрдгреЛрдВ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдкреНрд░рддреАрдд рд╣реЛрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП: Exist, SetText, Select, SetCheck, InnerHtml, рдЖрджрд┐ред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рд╣рдореЗрдВ Click, SendKeys, рдФрд░ Text рдХреЗ рд╕рд╛рде рд╕рдВрддреЛрд╖ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
- рд╡рд┐рднрд┐рдиреНрди рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдкрд░ рдХрдИ рд╕рдорд╕реНрдпрд╛рдПрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ рдФрд░ рдХреНрд░реЛрдо рдкрд░, рддрддреНрд╡ рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди IE рдкрд░ - рдирд╣реАрдВред рдореБрдЭреЗ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЛрдВ рдХреЛ рд▓рд┐рдЦрдирд╛ рд╣реИ, "рдмреИрд╕рд╛рдЦреА"
- рдкреНрд░рджрд░реНрд╢рдиред рд╣рд╛рдВ, рдбреНрд░рд╛рдЗрд╡рд░ рддреЗрдЬреА рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред IE рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣ рдмрд╛рдХреА рд╕реЗ рдЖрдЧреЗ рд╣реИ - рдПрдХ рдЦреЛрдЬ рд╕реЗрдХрдВрдб рд▓реЗ рд╕рдХрддреА рд╣реИ, рдХрднреА-рдХрднреА рджрд╕рд┐рдпреЛрдВ рд╕реЗрдХрдВрдб
рдЦреИрд░, рдмрд╣реБрдд рд╕рд╛рд░реА рд╕рдорд╕реНрдпрд╛рдПрдВ - рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рдорд╛рдзрд╛рдиред рдореИрдВ рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛ рдФрд░ рдЗрд╕ рднрд╛рдЧ рдореЗрдВ рдПрдХ рдмрд╛рд░ рдореЗрдВ рд╕рдм рдХреБрдЫ рдирд╣реАрдВ рдмрддрд╛ рдкрд╛рдКрдВрдЧрд╛ред рдПрдХ рд▓рдВрдмреА рдкреЛрд╕реНрдЯ рдирд┐рд░реНрдмрд╛рдз рд╣реЛрдЧреА, рдФрд░ рдЗрд╕реЗ рд▓рд┐рдЦрддреЗ рд╕рдордп рднреА, рдЙрддреНрд╕рд╛рд╣ рддреЗрдЬреА рд╕реЗ рдЧрд┐рд░рддрд╛ рд╣реИ) рдЗрд╕рд▓рд┐рдП, рдЗрд╕ рднрд╛рдЧ рдХреА рд╕рдВрдЦреНрдпрд╛ 2.1 рд╣реИ, рдЗрд╕рдореЗрдВ рдореИрдВ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдкрд░ рдЕрдкрдирд╛ рдЖрд╡рд░рдг рджрд┐рдЦрд╛рдКрдВрдЧрд╛ред
рд╕рдВрджрд░реНрдн
рднрд╛рдЧ 1: рдкрд░рд┐рдЪрдпрднрд╛рдЧ 2.1: рд╕реЗрд▓реЗрдирд┐рдпрдо рдПрдкреАрдЖрдИ рдЖрд╡рд░рдг - рдмреНрд░рд╛рдЙрдЬрд╝рд░рднрд╛рдЧ 2.2: рд╕реЗрд▓реЗрдирд┐рдпрдо рдПрдкреАрдЖрдИ рдЖрд╡рд░рдг - рд╡реЗрдмрдЗрдореЗрдВрдЯрднрд╛рдЧ 3: рд╡реЗрдмрдкреЗрдЬ - рдкреГрд╖реНрдареЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛рднрд╛рдЧ 4: рдЕрдВрдд рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдирд╛рдПрдХ рд░реВрдкрд░реЗрдЦрд╛ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рдирд╛рдЪрд▓реЛ рдЪрд▓рддреЗ рд╣реИрдВред рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдкрд░ рдЖрд╡рд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛: рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреНрд▓рд╛рд╕
рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдЖрдкрдХреЛ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд▓рдЧрддрд╛ред
рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╕рднреА IWebDriver- рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреЛрдб рдХреЛ рдПрдирдХреИрдкреНрд╕реБрд▓реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХрд╛рдпрд░ рдмрд╛рд╣рд░реА рд░реВрдк рд╕реЗ рдлреИрд▓рддреЗ рдирд╣реАрдВ рд╣реИрдВ, рдЕрд░реНрдерд╛рддред рдСрдЯреЛрдЯреЗрд╕реНрдЯ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рдкрд╛рд╕ рдбреНрд░рд╛рдЗрд╡рд░ рдХреА рд╕реАрдзреА рдкрд╣реБрдВрдЪ рдирд╣реАрдВ рд╣реЛрдЧреАред рдирддреАрдЬрддрди, рдРрд╕реА рд╡рд┐рдзрд┐рдпрд╛рдВ рд╣реИрдВ рдЬрд┐рдирдореЗрдВ рдПрдХ рд╣реА рдирд╛рдо рдХрд╛ рдбреНрд░рд╛рдЗрд╡рд░ рд╡рд┐рдзрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред
рдХреЛрдб рдореЗрдВ рдХреЛрдИ рдЯрд┐рдкреНрдкрдгреА рдирд╣реАрдВ рд╣реИ - рдпрд╣ рдПрдХ рдЕрдЪреНрдЫрд╛ рд╕реНрд╡рд░ рд╣реИ, рдФрд░ рдЬреИрд╕рд╛ рдХрд┐ рдПрдХ рд╕реНрдорд╛рд░реНрдЯ рд╡реНрдпрдХреНрддрд┐ рдиреЗ рдХрд╣рд╛: "рдХреЛрдб рдореЗрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ рдПрдХ рд╕реВрдк рдореЗрдВ рдмрд╛рд▓ рдХреА рддрд░рд╣ рд╣реЛрддреА рд╣реИрдВред рдХреНрдпрд╛ рдЖрдк рдмрд╛рд▓ рдХреЗ рд╕рд╛рде рд╕реВрдк рдЦрд╛рдПрдВрдЧреЗ? "
рдореИрдВ Microsoft рдХреЛрдб рдЕрдиреБрдмрдВрдз рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, рдХреЙрд▓ рд╕реЗ рдбрд░реЛ рдорддред
рдпрд╣ рднреА рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдП рдЧрдП рдЙрддреНрдкрд╛рдж рдореЗрдВ jquery рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ, рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреБрдЫ рдХреНрд░рд┐рдпрд╛рдПрдВ рдХреА рдЬрд╛рдПрдВрдЧреАред
рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╡рд░реНрдЧ 3 рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ:
- рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕
- рдХреНрд░реЛрдо
- рдЗрдВрдЯрд░рдиреЗрдЯ рдПрдХреНрд╕рдкреНрд▓реЛрд░рд░
рдпрд╣ рджреБрд░реНрднрд╛рдЧреНрдпрдкреВрд░реНрдг рд╣реИ рдХрд┐ рдУрдкреЗрд░рд╛ рдХреЗ рд▓рд┐рдП рдЕрднреА рддрдХ рдХреЛрдИ C # рдбреНрд░рд╛рдЗрд╡рд░ рдирд╣реАрдВ рд╣реИрдВ :(
рдорд╛рдирдХ рд╡рд┐рдзрд┐рдпреЛрдВ рдФрд░ рдЧреБрдгреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреИрд╕реЗ:
- рдкреНрд░рд╛рд░рдВрдн
- рдЫреЛрдбрд╝рдирд╛
- рдиреЗрд╡рд┐рдЧреЗрдЯ
- NavigateBack
- рддрд╛рдЬрд╝рд╛ рдХрд░рдирд╛
- WaitReadyState
- FindElements
- SelectedBrowser
- рдпреВрдЖрд░рдПрд▓
- рд╢реАрд░реНрд╖рдХ
- PageSource
- рдПрдЯ рдЕрд▓ред
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдирд╛рдо рдХрд╛рдлреА рд╕реНрдкрд╖реНрдЯ рд╣реИрдВ, рддреЛ рдЪрд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред
рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдп рднреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдП рдЧрдП:
- WaitAjax
- SwitchToFrame
- SwitchToPopupWindow
- AcceptAlert
- GetScreenshot + SaveScreenshot
- ResizeWindow
- ExecuteJavaScript
- DragAndDrop
- рдПрдЯ рдЕрд▓ред
namespace Autotests.Utilities { [Serializable] public enum Browsers { [Description("Windows Internet Explorer")] InternetExplorer, [Description("Mozilla Firefox")] Firefox, [Description("Google Chrome")] Chrome } public static class Browser { #region Public properties public static Browsers SelectedBrowser { get { return Settings.Default.Browser; } } public static Uri Url { get { WaitAjax(); return new Uri(WebDriver.Url); } } public static string Title { get { WaitAjax(); return string.Format("{0} - {1}", WebDriver.Title, EnumHelper.GetEnumDescription(SelectedBrowser)); } } public static string PageSource { get { WaitAjax(); return WebDriver.PageSource; } } #endregion #region Public methods public static void Start() { _webDriver = StartWebDriver(); } public static void Navigate(Uri url) { Contract.Requires(url != null); WebDriver.Navigate().GoToUrl(url); } public static void Quit() { if (_webDriver == null) return; _webDriver.Quit(); _webDriver = null; } public static void WaitReadyState() { Contract.Assume(WebDriver != null); var ready = new Func<bool>(() => (bool)ExecuteJavaScript("return document.readyState == 'complete'")); Contract.Assert(Executor.SpinWait(ready, TimeSpan.FromSeconds(60), TimeSpan.FromMilliseconds(100))); } public static void WaitAjax() { Contract.Assume(WebDriver != null); var ready = new Func<bool>(() => (bool)ExecuteJavaScript("return (typeof($) === 'undefined') ? true : !$.active;")); Contract.Assert(Executor.SpinWait(ready, TimeSpan.FromSeconds(60), TimeSpan.FromMilliseconds(100))); } public static void SwitchToFrame(IWebElement inlineFrame) { WebDriver.SwitchTo().Frame(inlineFrame); } public static void SwitchToPopupWindow() { foreach (var handle in WebDriver.WindowHandles.Where(handle => handle != _mainWindowHandler)) // TODO: { WebDriver.SwitchTo().Window(handle); } } public static void SwitchToMainWindow() { WebDriver.SwitchTo().Window(_mainWindowHandler); } public static void SwitchToDefaultContent() { WebDriver.SwitchTo().DefaultContent(); } public static void AcceptAlert() { var accept = Executor.MakeTry(() => WebDriver.SwitchTo().Alert().Accept()); Executor.SpinWait(accept, TimeSpan.FromSeconds(5)); } public static IEnumerable<IWebElement> FindElements(By selector) { Contract.Assume(WebDriver != null); return WebDriver.FindElements(selector); } public static Screenshot GetScreenshot() { WaitReadyState(); return ((ITakesScreenshot)WebDriver).GetScreenshot(); } public static void SaveScreenshot(string path) { Contract.Requires(!string.IsNullOrEmpty(path)); GetScreenshot().SaveAsFile(path, ImageFormat.Jpeg); } public static void DragAndDrop(IWebElement source, IWebElement destination) { (new Actions(WebDriver)).DragAndDrop(source, destination).Build().Perform(); } public static void ResizeWindow(int width, int height) { ExecuteJavaScript(string.Format("window.resizeTo({0}, {1});", width, height)); } public static void NavigateBack() { WebDriver.Navigate().Back(); } public static void Refresh() { WebDriver.Navigate().Refresh(); } public static object ExecuteJavaScript(string javaScript, params object[] args) { var javaScriptExecutor = (IJavaScriptExecutor)WebDriver; return javaScriptExecutor.ExecuteScript(javaScript, args); } public static void KeyDown(string key) { new Actions(WebDriver).KeyDown(key); } public static void KeyUp(string key) { new Actions(WebDriver).KeyUp(key); } public static void AlertAccept() { Thread.Sleep(2000); WebDriver.SwitchTo().Alert().Accept(); WebDriver.SwitchTo().DefaultContent(); } #endregion #region Private private static IWebDriver _webDriver; private static string _mainWindowHandler; private static IWebDriver WebDriver { get { return _webDriver ?? StartWebDriver(); } } private static IWebDriver StartWebDriver() { Contract.Ensures(Contract.Result<IWebDriver>() != null); if (_webDriver != null) return _webDriver; switch (SelectedBrowser) { case Browsers.InternetExplorer: _webDriver = StartInternetExplorer(); break; case Browsers.Firefox: _webDriver = StartFirefox(); break; case Browsers.Chrome: _webDriver = StartChrome(); break; default: throw new Exception(string.Format("Unknown browser selected: {0}.", SelectedBrowser)); } _webDriver.Manage().Window.Maximize(); _mainWindowHandler = _webDriver.CurrentWindowHandle; return WebDriver; } private static InternetExplorerDriver StartInternetExplorer() { var internetExplorerOptions = new InternetExplorerOptions { IntroduceInstabilityByIgnoringProtectedModeSettings = true, InitialBrowserUrl = "about:blank", EnableNativeEvents = true }; return new InternetExplorerDriver(Directory.GetCurrentDirectory(), internetExplorerOptions); } private static FirefoxDriver StartFirefox() { var firefoxProfile = new FirefoxProfile { AcceptUntrustedCertificates = true, EnableNativeEvents = true }; return new FirefoxDriver(firefoxProfile); } private static ChromeDriver StartChrome() { var chromeOptions = new ChromeOptions(); var defaultDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\..\Local\Google\Chrome\User Data\Default"; if (Directory.Exists(defaultDataFolder)) { Executor.Try(() => DirectoryExtension.ForceDelete(defaultDataFolder)); } return new ChromeDriver(Directory.GetCurrentDirectory(), chromeOptions); } #endregion } }
рдпрд╣ рдЯрд┐рдкреНрдкрдгреА рдХрд░рдиреЗ рд▓рд╛рдпрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ Settings.Default.Browser рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИ рдЬреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдЧреБрдгреЛрдВ рдореЗрдВ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ Executor.SpinWait рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╕рд╣рд╛рдпрдХ рд╣реИ рдЬреЛ рдПрдХ рд╢рд░реНрдд рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЯрд╛рдЗрдордЖрдЙрдЯ рдХреЗ рд╕рд╛рде рдкреВрд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ / рдЧрд▓рдд рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬрд╛рджреВ рдХреЗ рддрд╛рд░ рднреА рд╣реИрдВ, рдХреНрд╖рдорд╛ рдХрд░реЗрдВ)