рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░! рдореЗрд░рд╛ рдирд╛рдо
рдЕрд░реНрдЯрд┐рдУрдо рд╕реЛрдХреЛрд╡реЗрдЯреНрд╕ рд╣реИ ред рдореИрдВ рдПрдЯрд▓рд╕ рдкрд░ рдЕрдкрдиреЗ рд▓реЗрдЦ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ: HTML рдПрд▓рд┐рдореЗрдВрдЯреНрд╕ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рдкреБрдирд░реНрдЬрдиреНрдо, рдЬреЛ рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИред
рд╡рд┐рд╡рд░рдг рдореЗрдВ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рдкреВрдЫрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ: рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдХрд┐рддрдиреЗ рд░реИрдкрд░ рд╣реИрдВ рдЬреЛ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ? рдкреГрд╖реНрда рддрддреНрд╡, рд╕реНрдХреНрд░реАрдирдкреНрд▓реЗ, рд▓реЛрдб рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдШрдЯрдХ, рдЪрд╛рд▓рд╛рди рдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛ ...
рдФрд░ рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рд╣рдо рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкрд░ рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдПрдХ рдкреГрд╖реНрда рдСрдмреНрдЬреЗрдХреНрдЯ рд▓реЗрддреЗ рд╣реИрдВ, рдкреНрд░реЙрдХреНрд╕реА рдкреИрдЯрд░реНрди рдХреЛ рддреЗрдЬ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЬрд╛рд╡рд╛ 8 рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдПрдХ рд╕рд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ?
рдпрджрд┐ рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реИ, рддреЛ рдореИрдВ рдмрд┐рд▓реНрд▓реА рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВред

рдкрд░рд┐рдЪрдп
рдорд╛рдирдХ PageObject рдбрд┐рдЬрд╝рд╛рдЗрди рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдХрдИ рд╕рдорд╕реНрдпрд╛рдПрдВ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИрдВ:
рддрддреНрд╡реЛрдВ рдХрд╛ рджреЛрд╣рд░рд╛рд╡public class MainPage { @FindBy(xpath = ".//div[@class = 'header']") private Header header; } public class AnyOtherPage { @FindBy(xpath = ".//div[@class = 'header']") private Header header; }
рдпрд╣рд╛рдВ, рд╣реЗрдбрд░ рдмреНрд▓реЙрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рднрд┐рдиреНрди рдкреЗрдЬрдСрдмреНрдЬреЗрдХреНрдЯ рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдП рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЕрднрд╛рд╡ public class EditUserPage { @FindBy(xpath = "//div[text()='Text_1']") private TextBlock lastActivity; @FindBy(xpath = "//div[text()='Text_2']") private TextBlock blockReason; }
рдпрд╣ рдЙрджрд╛рд╣рд░рдг рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рд╕рдВрдкрд╛рджрди рдкреГрд╖реНрда рдХреЗ рддрддреНрд╡реЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рджреЛ TextBlock рддрддреНрд╡реЛрдВ рдореЗрдВ рдХреЗрд╡рд▓ рдкрд╛рда рдорд╛рди ("Text_1" рдФрд░ "Text_2") рдореЗрдВ рдЕрдВрддрд░ рдХреЗ рд╕рд╛рде рд▓рдЧрднрдЧ рд╕рдорд╛рди рд▓реЛрдХреЗрдЯрд░ рд╣реЛрддрд╛ рд╣реИред
рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдХреЛрдб public class UserPage { @FindBy(xpath = "//div[text()='']/input") private UfsTextInput innerPhone; @FindBy(xpath = "//div[text()='Email']/input") private UfsTextInput email; @FindBy(xpath = "//button[text()='']") private UfsButton save; @FindBy(xpath = "//button[text()='']") private UfsButton toUsersList; }
рд░реЛрдЬрдорд░реНрд░рд╛ рдХреЗ рдХрд╛рдо рдореЗрдВ, рдЖрдк рдПрдХ рд╣реА рддрддреНрд╡ рдХреЗ рд╕рд╛рде рдХреЛрдб рдХреА рдХрдИ рд▓рд╛рдЗрдиреЛрдВ рд╕реЗ рдорд┐рд▓рдХрд░ рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рдРрд╕реА рдХрдХреНрд╖рд╛рдПрдВ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП "рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ" рд╣реИрдВред
рдЪрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдмрдбрд╝рд╛ рд╡рд░реНрдЧ public class MainSteps { public void hasText(HtmlElement e, Matcher m) public void hasValue(HtmlElement e, Matcher m) public void linkContains(HtmlElement e, String s) public void hasSize(List<HtmlElement> e, Matcher m) public void hasItem(List<HtmlElement> e, Matcher m)
рд╕рдордп рдХреЗ рд╕рд╛рде, рддрддреНрд╡реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд░рдгреЛрдВ рдХрд╛ рд╡рд░реНрдЧ рдмрдврд╝рддрд╛ рд╣реИред рдЕрдзрд┐рдХ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдХреЛрдИ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рддрд░реАрдХреЗ рди рд╣реЛрдВред
рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рджреБрдирд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЖрдкрдХрд╛ рдЧрд╛рдЗрдб
HTML рдПрд▓рд┐рдореЗрдВрдЯ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рдкреБрдирд░реНрдЬрдиреНрдо рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдЙрдкрд░реЛрдХреНрдд рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдирд╛ рд╣реИ, рдПрдХ рдкрд░реАрдХреНрд╖рдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдирд╛, рд╕реВрдЪрд┐рдпреЛрдВ рдФрд░ рдЕрдкреЗрдХреНрд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХ рд╡рд┐рдЪрд╛рд░рд╢реАрд▓ рдХрд╛рд░реНрдп, рд╕рд╛рде рд╣реА рд╡рд┐рд╕реНрддрд╛рд░ рдкреНрд░рдгрд╛рд▓реА рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд▓рд┐рдП рдЯреВрд▓ рдХреЛ рдареАрдХ рдХрд░рдирд╛ред
рдПрдЯрд▓рд╕ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдкреИрдЯрд░реНрди рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдпреВрдЖрдИ рдСрдЯреЛ-рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдИ рдкреАрдврд╝реА рдХрд╛ рдЬрд╛рд╡рд╛ рдлреНрд░реЗрдорд╡рд░реНрдХ рд╣реИред рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рддрддреНрд╡реЛрдВ рдХреЗ рдкреЗрдбрд╝ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рдХрдИ рд╡рд┐рд░рд╛рд╕рдд рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЕрдВрддрддрдГ рдЖрдкрдХреЗ рдСрдЯреЛрдЯреЗрд╕реНрдЯреНрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдХреЛрдб рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рдореБрдЦреНрдп рдирд╡рд╛рдЪрд╛рд░ рдорд╛рдирдХ рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдмрдЬрд╛рдп рдЗрдВрдЯрд░рдлреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реИред
рдпрд╣ рдХреНрдпрд╛ github.com рдореБрдЦрдкреГрд╖реНрда рд╡рд┐рд╡рд░рдг рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:
public interface MainPage extends WebPage, WithHeader { @FindBy("//a[contains(text(), 'Or start a free)]") AtlasWebElement trial(); }
рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдПрдХ рддрддреНрд╡ рдХреЗ рд╕рд╛рде GitHub рд╕рд╛рдЗрдЯ рдХреЗ рдореБрдЦреНрдп рдкреГрд╖реНрда рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ рдФрд░ WebPage рдФрд░ WithHeader рдкрд░рддреЛрдВ рд╕реЗ рдПрдХрд╛рдзрд┐рдХ рд╡рдВрд╢рд╛рдиреБрдХреНрд░рдо (рдЙрджрд╛рд╣рд░рдг рдХреЗрд╡рд▓ рд╢реИрдХреНрд╖рд┐рдХ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЕрдзрд┐рдХрд╛рдВрд╢ рд╡реЗрдм рддрддреНрд╡ рдЫреЛрдбрд╝ рджрд┐рдП рдЧрдП рд╣реИрдВ)ред
рдлреНрд░реЗрдорд╡рд░реНрдХ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛
рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдПрдЯрд▓рд╕ рдореЗрдВ рддреАрди рдореЙрдбреНрдпреВрд▓ рд╣реЛрддреЗ рд╣реИрдВ:
- рдПрдЯрд▓рд╕ рдХреЛрд░
- рдПрдЯрд▓рд╕-webdriver
- рдПрдЯрд▓рд╕-appium
рдПрдЯрд▓рд╕-рдХреЛрд░ рдЗрдВрдЯрд░рдлреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмреБрдирд┐рдпрд╛рджреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рдЗрдВрдЯрд░рдлреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдмрд╣реБрдд рд╡рд┐рдЪрд╛рд░ рдкреНрд░рд╕рд┐рджреНрдз рд░реЗрдЯреНрд░реЛрдлрд┐рдЯ рдЯреВрд▓ рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдпреВрдЖрдИ рд╡реЗрдм рдФрд░ рдпреВрдЖрдИ рдореЛрдмрд╛рдЗрд▓ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреНрдп рджреЛ
рдПрдЯрд▓рд╕-рд╡реЗрдмрдбреНрд░рд╛рдЗрд╡рд░ рдФрд░
рдПрдЯрд▓рд╕-рдРрдкрд┐рдпрдо рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡реЗрдм рдкреЗрдЬреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореБрдЦреНрдп рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рд╡реЗрдмрдкреЗрдЬ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ, рдФрд░ рдореЛрдмрд╛рдЗрд▓ рд╕реНрдХреНрд░реАрди рдХреЗ рд▓рд┐рдП - рд╕реНрдХреНрд░реАрдиред рд╡реИрдЪрд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ, рдПрдЯрд▓рд╕-рд╡реЗрдмрдбреНрд░рд╛рдЗрд╡рд░ рдФрд░ рдПрдЯрд▓рд╕-рдПрдкрд┐рдпрдо рдПрдХреНрд╕рдЯреЗрдВрд╢рди (рдкреИрдХреЗрдЬ *ред рдХрд╕реНрдЯрдореЗрд╢рди) рдкрд░ рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред
рддрддреНрд╡реЛрдВ

рдпрд╣ рдЙрдкрдХрд░рдг UI рддрддреНрд╡реЛрдВ (WebElement рд╡рд░реНрдЧ рдХрд╛ рдПрдХ рдПрдирд╛рд▓реЙрдЧ) рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
рджреЛ рд╡рд┐рд╢реЗрд╖ рд╡рд░реНрдЧреЛрдВ рдХреЗ рд╕рд╛рде рдЖрддрд╛ рд╣реИред
AtlasWebElement рдФрд░
AtlasMobileElement рдХреЛ рдкреВрд░рдХ рдФрд░
рдкреНрд░рддреАрдХреНрд╖рд╛ рд╡рд┐рдзрд┐ рджреНрд╡рд╛рд░рд╛ рдкреВрд░рдХ
рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП ред (рдЗрди рддрд░реАрдХреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рд▓реЗрдЦ рдореЗрдВ рдЖрдЧреЗ рд╣реЛрдЧрд╛)ред
рдЙрдкрдХрд░рдг рдЙрдкрд░реЛрдХреНрдд рд╡рд░реНрдЧреЛрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдХреЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдШрдЯрдХреЛрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ рдПрдХ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рддрддреНрд╡ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдореБрдЦреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ
рдЖрдЗрдП рдЯреВрд▓ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдкрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:
рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдмрдЬрд╛рдп рдЗрдВрдЯрд░рдлреЗрд╕рдорд╛рдирдХ PageObjects рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╕рдордп, рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдмрдЬрд╛рдп рдЗрдВрдЯрд░рдлреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
public interface MainPage extends WebPage, WithHeader { @FindBy("//a[contains(text(), 'Or start a free trial of Enterprise Server')]") AtlasWebElement trial(); }
рдпрд╣ рдЙрджрд╛рд╣рд░рдг GitHub рдкреНрд░рд╛рд░рдВрдн рдкреГрд╖реНрда рдкрд░ рд▓рд┐рдВрдХ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред
рддрддреНрд╡реЛрдВ рдХрд╛ рдкреИрд░рд╛рдореАрдЯрд░рдХрд▓реНрдкрдирд╛ рдХреАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЦреЗрддреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд░реВрдк рд╣реИ:

рдЗрд╕рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ @FindBy рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде 11 рдЪрд░ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░ рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдЧреЗрдЯрдЯрд░ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВред
рдПрдЯрд▓рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдЖрдкрдХреЛ рдХреЗрд╡рд▓
рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдПрдЯрд▓рд╕рд╡реЗрдм рдПрд▓рд┐рдореЗрдВрдЯ рдПрд▓рд┐рдореЗрдВрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
public interface MainPage extends WebPage { @FindBy("//div[text()='{{ text }}']/input") AtlasWebElement input(@Param("text") String text); }
рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
@Test public void simpleTest() { onMainPage().input("First Name").sendKeys("*"); onMainPage().input("Postcode").sendKeys("*"); onMainPage().input("Email").sendKeys("*"); }
рд╣рдо рд╡рд╛рдВрдЫрд┐рдд рдкреГрд╖реНрда рдХреА рдУрд░ рдореБрдбрд╝рддреЗ рд╣реИрдВ, рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рддрддреНрд╡ рдХреЗ рд╕рд╛рде рдЖрд╡рд╢реНрдпрдХ рдХреНрд░рд┐рдпрд╛рдПрдВ рдХрд░рддреЗ рд╣реИрдВред рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд┐рдзрд┐ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреА рд╣реИред
рдПрдХрд╛рдзрд┐рдХ рд╡рдВрд╢рд╛рдиреБрдХреНрд░рдордпрд╣ рдкрд╣рд▓реЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдПрдХ рдмреНрд▓реЙрдХ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣реЗрдбрд░), рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рднрд┐рдиреНрди рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреЛрдб рдХрд╛ рджреЛрд╣рд░рд╛рд╡ рд╣реИред
рдПрдХ рд╣реИрдбрд░ рдЬреАрдердм рд╣реИред

рд╣рдо рдЗрд╕ рдмреНрд▓реЙрдХ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ (рдЕрдзрд┐рдХрд╛рдВрд╢ рд╡реЗрдм рддрддреНрд╡реЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ):
public interface Header extends AtlasWebElement { @FindBy(".//input[contains(@class,'header-search-input')]") AtlasWebElement searchInput(); }
рдЗрд╕рдХреЗ рдмрд╛рдж, рдПрдХ рдкрд░рдд рдмрдирд╛рдПрдВ рдЬреЛ рдХрд┐рд╕реА рднреА рдкреЗрдЬ рд╕реЗ рдЬреБрдбрд╝реА рд╣реЛ:
public interface WithHeader { @FindBy("//header[contains(@class,'Header')]") Header header(); }
рд╣рдо рд╣реЗрдбрд░ рдмреНрд▓реЙрдХ рдХреЗ рд╕рд╛рде рдореБрдЦреНрдп рдкреГрд╖реНрда рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред
public interface MainPage extends WebPage, WithHeader { @FindBy("//a[contains(text(), 'Or start a)]") AtlasWebElement trial(); }
рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЖрдк рдЕрдзрд┐рдХ рдкрд░рддреЗрдВ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╡рд╛рдВрдЫрд┐рдд рдкреГрд╖реНрда рд╕реЗ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣реЗрдбрд░, рдлреБрдЯрд░, рд╕рд╛рдЗрдбрдмрд╛рд░ рдкрд░рддреЛрдВ рдХреЛ рдореБрдЦреНрдп рдкреГрд╖реНрда рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВред
public interface MainPage extends WithHeader, WithFooter, WithSidebar {}
рдЪрд▓реЛ рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред рд╣реИрдбрд░ рдореЗрдВ 4 рдмрдЯрди, 3 рдбреНрд░реЙрдк-рдбрд╛рдЙрди рдореЗрдиреВ рдФрд░ рдПрдХ рдЦреЛрдЬ рдлрд╝реАрд▓реНрдб рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:

рдЪрд▓реЛ рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛
рдмрдЯрди рддрддреНрд╡ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рддрддреНрд╡ рдХреЗ рд╕рд╛рде рдЪрд╛рд░ рдмрдЯрди рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВред
public interface Button extends AtlasWebElement { @FindBy(".//a[contains(., '{{ value }}')]") AtlasWebElement selectButton(@Param("value") String value); }
рдмрдЯрди рдмрдЯрди рдХреЛ рд╣реЗрдбрд░ рд▓реЗрдпрд░ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдЧрд┐рдЯрд╣рдм рд╣реЗрдбрд░ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред
public interface Header extends WithButton { тАж }
рдПрдХ рдЕрд▓рдЧ
рдмрдЯрди рддрддреНрд╡ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдХреА рд╡рд┐рднрд┐рдиреНрди рдкрд░рддреЛрдВ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЬрд▓реНрджреА рд╕реЗ рд╡рд╛рдВрдЫрд┐рдд рдкреГрд╖реНрда рдкрд░ рд╡рд╛рдВрдЫрд┐рдд рддрддреНрд╡ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред
рдПрдХ рдЙрджрд╛рд╣рд░рдг:
@Test public void simpleTest() { onMainPage().open("https://github.com"); onMainPage().header().button("Priing").click(); }
рдкрд░реАрдХреНрд╖рдг рдХреА рджреВрд╕рд░реА рдкрдВрдХреНрддрд┐ рдореЗрдВ, рд╕рд╛рдЗрдЯ рдХрд╛ рд╣реЗрдбрд░ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлрд┐рд░ рд╣рдо рдорд╛рди "рдореВрд▓реНрдп" рдХреЗ рд╕рд╛рде рдкреИрд░рд╛рдореАрдЯрд░ рдХрд┐рдП рдЧрдП рдмрдЯрди рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдХреНрд▓рд┐рдХ рдХрд░рддреЗ рд╣реИрдВред
рдкрд░реАрдХреНрд╖рдг рдХрд┐рдП рдЧрдП рд╕рд╛рдЗрдЯ рдкрд░ рдХрд╛рдлреА рдХреБрдЫ рддрддреНрд╡ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдкреГрд╖реНрда рд╕реЗ рдкреГрд╖реНрда рддрдХ рджреЛрд╣рд░рд╛рддреЗ рд╣реИрдВред рдорд╛рдирдХ рдкреГрд╖реНрда рдСрдмреНрдЬреЗрдХреНрдЯ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рдЙрди рд╕рднреА рдХрд╛ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдЙрдиреНрд╣реЗрдВ рдПрдХ рдмрд╛рд░ рд╡рд░реНрдгрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЬрд╣рд╛рдВ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рдЙрдиреНрд╣реЗрдВ рдХрдиреЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╕рдордп рдХреА рдмрдЪрдд рдФрд░ рдХреЛрдб рдХреА рд▓рд╛рдЗрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реНрдкрд╖реНрдЯ рд╣реИред
рдбрд┐рдлрд╝реЙрд▓реНрдЯ рддрд░реАрдХреЗрдЬрд╛рд╡рд╛ 8 рдиреЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рддрд░реАрдХреЗ рдкреЗрд╢ рдХрд┐рдП, рдЬрд┐рдирдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд╛рдВрдЫрд┐рдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ "рд╣рд╛рдирд┐рдХрд╛рд░рдХ" рддрддреНрд╡ рд╣реИ: рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЪреЗрдХрдмреЙрдХреНрд╕ рдЬреЛ рдпрд╛ рддреЛ рдЪрд╛рд▓реВ рдпрд╛ рдмрдВрдж рд╣реИред рдХрдИ рдкрд░рд┐рджреГрд╢реНрдп рдЗрд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЧреБрдЬрд░рддреЗ рд╣реИрдВред рдЕрдХреНрд╖рдо рд╣реЛрдиреЗ рдкрд░ рдЪреЗрдХрдмреЙрдХреНрд╕ рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ:
if(onMainPage().rentFilter().checkbox("").getAttribute("class").contains("disabled")) { onMainPage().rentFilter().checkbox("").click(); }
рдЗрд╕ рд╕рднреА рдХреЛрдб рдХреЛ рдЪрд░рдг рд╡рд░реНрдЧ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рддрддреНрд╡ рдХреЗ рдмрдЧрд▓ рдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╡рд┐рдзрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рд░рдЦрдирд╛ рд╕рдВрднрд╡ рд╣реИред
public interface Checkbox extends AtlasWebElement { @FindBy("//...") AtlasWebElement checkBox((@Param("value") String value); default void selectCheckbox(String value) { if (checkBox(value).getAttribute("class").contains("disabled")) { checkBox(value).click(); } } }
рдЕрдм рдкрд░реАрдХреНрд╖рд╛ рдореЗрдВ рдХрджрдо рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛:
onMainPage().rentFilter().selectCheckbox("");
рдПрдХ рдФрд░ рдЙрджрд╛рд╣рд░рдг рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдПрдХ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕рдлрд╛рдИ рдФрд░ рдЯрд╛рдЗрдкрд┐рдВрдЧ рд╡рд░реНрдгреЛрдВ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
onMainPage().header().input("GitHub").clear(); onMainPage().header().input("GitHub").sendKeys("*");
рдПрдХ рдРрд╕реА рд╡рд┐рдзрд┐ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ рдЬреЛ рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╕рд╛рдлрд╝ рдХрд░реЗ рдФрд░ рддрддреНрд╡ рдХреЛ рд╕реНрд╡рдпрдВ рд▓реМрдЯрд╛рдП:
public interface Input extends AtlasWebElement { @FindBy("//xpath") AtlasWebElement input(@Param("value") String value); default AtlasWebElement withClearInput(String value) { input(value).clear(); return input(value); } }
рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдзрд┐ рдореЗрдВ, рдЪрд░рдг рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
onMainPage().header().withClearInput("GitHub").sendKeys("Atlas");
рдЗрд╕ рддрд░рд╣, рддрддреНрд╡ рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдкреБрдирд░реНрдкреНрд░рдпрд╛рд╕ (рдкреБрди: рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ)рдПрдЯрд▓рд╕ рдореЗрдВ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд░рд┐рдЯреНрд░реАрдЯ рд╣реИрдВред рдЖрдкрдХреЛ
NotFoundException ,
StaleElementReferenceException рдФрд░
WebDriverException рдЬреИрд╕реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЖрдк рд╕реЗрд▓реЗрдирд┐рдпрдо API рдХреА рд╕реНрдкрд╖реНрдЯ рдФрд░ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдЕрдкреЗрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреА рднреВрд▓ рд╕рдХрддреЗ рд╣реИрдВред
onSite().onSearchPage("Junit 5").repositories().waitUntil(hasSize(10));
рдпрджрд┐ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рдХрд┐рд╕реА рдмрд┐рдВрджреБ рдкрд░ рдЖрдкрдиреЗ рдПрдХ рдЕрдкрд╡рд╛рдж рдкрдХрдбрд╝рд╛ рд╣реИ, рддреЛ рдЪрд░рдг рд╢реБрд░реБрдЖрдд рд╕реЗ рджреЛрд╣рд░рд╛рддрд╛ рд╣реИред
рдЙрд╕ рд╕рдордп рдЕрдВрддрд░рд╛рд▓ рдХреЛ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ рдЬрд┐рд╕рдХреЗ рджреМрд░рд╛рди рдЖрдк рджреЛрд╣рд░рд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреА рдЖрд╡реГрддреНрддрд┐ред
Atlas atlas = new Atlas(new WebDriverConfiguration(driver)) .context(new RetryerContext(new DefaultRetryer(3000L, 1000L, Collections.singletonList(Throwable.class))));
рд╣рдо рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рдПрдХ рдмрд╛рд░ рдХреЗ рдорддрджрд╛рди рджрд░ рдХреЗ рд╕рд╛рде рддреАрди рд╕реЗрдХрдВрдб рдХреЗ рд▓рд┐рдП рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВред
рд╣рдо
рд░рд┐рдЯреНрд░реА рдПрдиреЛрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЖрдЗрдЯрдо рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдХреНрд╖рд╛ рдХреЛ рднреА рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╕рднреА рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдП, рдЦреЛрдЬ 3 рд╕реЗрдХрдВрдб рдХреЗ рднреАрддрд░ рд╣реЛрдЧреА, рдФрд░ рдПрдХ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ 20 рд╣реЛрдЧреАред
@Retry(timeout = 20_000L, polling = 2000L) @IOSFindBy(xpath = "//XCUIElementTypeSearchField[@name='Search Wikipedia']") @AndroidFindBy(xpath = "//*[contains(@text, 'Search Wikipedia')]") AtlasMobileElement searchWikipedia();
рд╕реВрдЪрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВрдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░, рдЙрдкрдХрд░рдг рд╕реВрдЪрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ? рдПрдХ рдЗрдирдкреБрдЯ рдЯреИрдЧ рдХреЗ рд╕рд╛рде рдПрдХ рдХреНрд╖реЗрддреНрд░ рд╣реИ рдЬрд╣рд╛рдВ рд╣рдо рдкрд╛рда рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВ, рдлрд┐рд░ рдПрдХ рдбреНрд░реЙрдк-рдбрд╛рдЙрди рд╕реВрдЪреА рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИ, рддрддреНрд╡ рддреБрд░рдВрдд рдкреНрд░рдХрдЯ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред

рдЗрд╕ рддрд░рд╣ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрд╕реНрдерд╛ рдПрд▓реАрдореЗрдВрдЯреНрд╕рдХреЙрд▓рд╢рди рд╣реИред рдЗрд╕рдХреА рдорджрдж рд╕реЗ рд╕реВрдЪрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдХрд╛рдо рд╣реИред
public interface ContributorsPage extends WebPage, WithHeader { @FindBy(".//ol[contains(@class, 'contrib-data')]//li[contains(@class, 'contrib-person')]") ElementsCollection<RepositoryCard> hovercards(); }
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
onSite().onContributorsPage().hovercards().waitUntil(hasSize(4));
рддрддреНрд╡реЛрдВ рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рдирд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреА рд╕реВрдЪреА рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдирд╛ рднреА рд╕рдВрднрд╡ рд╣реИред
рд╕реНрдорд╛рд░реНрдЯ рдЬреЛрд░рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ,
AtlasWebElement рдФрд░
AtlasMobileElement рд╕рдВрд╕реНрдерд╛рдПрдВ рдЪреЗрдХ (рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ) рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡реЗрдЯ рдпреВрдЯрд┐рд▓рд┐рдЯ рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдРрд╕рд╛ рдХреНрдпреЛрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ? рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд╕реНрдХреНрд░рд┐рдкреНрдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд░рд┐рдкреЛрд░реНрдЯ рдЪрд▓рд╛рдиреЗ рдХреЗ рд╕рдордп рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдПред рдЕрдзрд┐рдХрд╛рдВрд╢ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЬрд╛рдВрдЪ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдЕрдВрдд рдореЗрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВ: рд╡реЗ рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкрд░реАрдХреНрд╖рдг рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдХреЗ рд▓рд┐рдП рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рдФрд░ рдПрдХ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдкрд░реАрдХреНрд╖рдг рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдХреЗ рд▓рд┐рдП рдордзреНрдпрд╡рд░реНрддреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рдЙрддреНрдкрд╛рдж рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреА рд╣реИ, рддреЛ рдпрд╣ рдорд╛рди рд▓реЗрдирд╛ рддрд░реНрдХрд╕рдВрдЧрдд рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдЕрдкрд╡рд╛рдж рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВ, рдЕрдиреНрдпрдерд╛ рдПрдХ RuntexExceptionред


рд▓реБрднрд╛рдирд╛ рддреБрд░рдВрдд рджрд┐рдЦрд╛рдПрдЧрд╛ рдХрд┐ рд╣рдо рдХреНрдпрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░ рд░рд╣реЗ рд╣реИрдВ: рдпрд╛ рддреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЙрддреНрдкрд╛рдж рджреЛрд╖ рд╣реИ (рдПрдлрдЯреА рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдХрд╛рдо рд▓реЗрддрд╛ рд╣реИ), рдпрд╛ рдСрдЯреЛрдЯреЗрд╕реНрдЯ рдЯреВрдЯ рдЬрд╛рддрд╛ рд╣реИ (рдПрдЯреА рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рд╕рдордЭрддрд╛ рд╣реИ)ред
рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдореЙрдбрд▓
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдкрд╛рд╕ рдЙрдкрдХрд░рдг рдХреА рдмреБрдирд┐рдпрд╛рджреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдпрд╛ рдЕрдкрдиреА рд╕реНрд╡рдпрдВ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рд╣реИред рдПрдЯрд▓рд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдореЙрдбрд▓ JUnit 5 рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдореЙрдбрд▓ рдХреЗ рд╕рдорд╛рди рд╣реИред рдПрдЯрд▓рд╕-рд╡реЗрдмрдбреНрд░рд╛рдЗрд╡рд░ рдФрд░ рдПрдЯрд▓рд╕-рдПрдкрд┐рдпрдо рдореЙрдбреНрдпреВрд▓ рд╡рд┐рд╕реНрддрд╛рд░ рдкрд░ рдмрдирд╛рдП рдЧрдП рд╣реИрдВред рдпрджрд┐ рдЖрдк рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рд╕реНрд░реЛрдд рдХреЛрдб рджреЗрдЦреЗрдВред
рдЖрдЗрдП рд╣рдо рдПрдХ рд╕рд╛рд░ рдЙрджрд╛рд╣рд░рдг рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВ: рдЗрдВрдЯрд░рдиреЗрдЯ рдПрдХреНрд╕рдкреНрд▓реЛрд░рд░ 11 рдХреЗ рд▓рд┐рдП рдпреВрдЖрдИ-рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ (рдХреБрдЫ рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдпрд╣ рдЕрднреА рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ)ред рдРрд╕реЗ рд╕рдордп рд╣реЛрддреЗ рд╣реИрдВ рдЬрдм рддрддреНрд╡реЛрдВ рдкрд░ рдорд╛рдирдХ рдХреНрд▓рд┐рдХ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЖрдк рдЬреЗрдПрд╕-рдХреНрд▓рд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк рд╕рдВрдкреВрд░реНрдг рдкрд░реАрдХреНрд╖рдг рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкрд░ рдХреНрд▓рд┐рдХ рдХреЛ рдЕрд╕реНрдерд╛рдпреА рд░реВрдк рд╕реЗ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реИрдВред
onMainPage().header().button("en").click();
рдпрд╣ рдХреИрд╕реЗ рдХрд░рдирд╛ рд╣реИ?
рдПрдХ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдмрдирд╛рдПрдВ рдЬреЛ MethodExtension рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред
public class JSClickExt implements MethodExtension { @Override public Object invoke(Object proxy, MethodInfo methodInfo, Configuration config) { final WebDriver driver = config.getContext(WebDriverContext.class) .orElseThrow(() -> new AtlasException("Context doesn't exist")).getValue(); final JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("arguments[0].click();", proxy); return proxy; } @Override public boolean test(Method method) { return method.getName().equals("click"); } }
рд╣рдо рджреЛ рддрд░реАрдХреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдкрд░реАрдХреНрд╖рдг () рд╡рд┐рдзрд┐ рдореЗрдВ, рд╣рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдХреНрд▓рд┐рдХ рд╡рд┐рдзрд┐ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рддреЗ рд╣реИрдВред рдЖрд╣реНрд╡рд╛рди рд╡рд┐рдзрд┐ рдЖрд╡рд╢реНрдпрдХ рддрд░реНрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреА рд╣реИред рдЕрдм рддрддреНрд╡ рдкрд░ рдХреНрд▓рд┐рдХ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣реЛрдЧрд╛ред
рд╣рдо рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХрдиреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВ:
atlas = new Atlas(new WebDriverConfiguration(driver, "https://github.com")) .extension(new JSClickExt());
рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреА рдорджрдж рд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдмрдирд╛рдирд╛ рдФрд░ рдЕрдиреНрдп рджрд┐рд▓рдЪрд╕реНрдк рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ - рдпрд╣ рд╕рдм рдЖрдкрдХреА рдХрд▓реНрдкрдирд╛ рдФрд░ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред
PageObjects (рд╡реЗрдмрд╕рд╛рдЗрдЯ) рдХреЗ рд▓рд┐рдП рдПрдХрд▓ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдмрд┐рдВрджреБрдЙрдкрдХрд░рдг рдЖрдкрдХреЛ рдЕрдкрдиреЗ рд╕рднреА рдкреГрд╖реНрда рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдФрд░ рдХреЗрд╡рд▓ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рд╕рд╛рдЗрдЯ рдЗрдХрд╛рдИ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
public interface GitHubSite extends WebSite { @Page MainPage onMainPage(); @Page(url = "search") SearchPage onSearchPage(@Query("q") String value); @Page(url = "{profile}/{project}/tree/master/") ProjectPage onProjectPage(@Path("profile") String profile, @Path("project") String project); @Page ContributorsPage onContributorsPage(); }
рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдкреЗрдЬ рдХреЗ рд▓рд┐рдП рддреЗрдЬрд╝ рдпреВрдЖрд░рдПрд▓, рдХреНрд╡реЗрд░реА рдкреИрд░рд╛рдореАрдЯрд░ рдФрд░ рдкрде рдЦрдВрдб рд╕реЗрдЯ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред
onSite().onProjectPage("qameta", "atlas").contributors().click();
рдКрдкрд░ рдХреА рд░реЗрдЦрд╛ рдореЗрдВ рджреЛ рдкрде рдЦрдВрдб (рдХреНрдпреВрдореЗрдЯрд╛ рдФрд░ рдПрдЯрд▓рд╕) рд╣реИрдВ, рдЬреЛ
github.com/qameta/atlas/tree/master рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдореБрдЦреНрдп рд▓рд╛рдн рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд┐рдП рдмрд┐рдирд╛ рд╡рд╛рдВрдЫрд┐рдд рдкреГрд╖реНрда рдХреЛ рддреБрд░рдВрдд рдЦреЛрд▓рдирд╛ рд╕рдВрднрд╡ рд╣реИред
@Test public void usePathWebSiteTest() { onSite().onProjectPage("qameta", "atlas").contributors().click(); onSite().onContributorsPage().hovercards().waitUntil(hasSize(4)); }
рдореЛрдмрд╛рдЗрд▓ рддрддреНрд╡ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВрдореЛрдмрд╛рдЗрд▓ рддрддреНрд╡ (AtlasMobileElement) рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдп рдХрд░рдирд╛ AtlasWebElement рд╡реЗрдм рддрддреНрд╡ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд╕рдорд╛рди рд╣реИред рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, AtlasMobileElement рдореЗрдВ рддреАрди рддрд░реАрдХреЗ рдЬреЛрдбрд╝реЗ рдЧрдП рд╣реИрдВ: рд╕реНрдХреНрд░реАрди рдХреЛ рдКрдкрд░ / рдиреАрдЪреЗ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдирд╛ (рд╕реНрдХреНрд░реЙрд▓рдЕрдк / рд╕реНрдХреНрд░реЙрд▓рдбрд╛рдЙрди) рдФрд░ рд╣реЛрд▓реНрдб (рд▓реЙрдиреНрдЧрдкреНрд░реЗрд╕) рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рдЖрдЗрдЯрдо рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдирд╛ред
рдореИрдВ рдЖрдкрдХреЛ рд╡рд┐рдХрд┐рдкреАрдбрд┐рдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреА рдореБрдЦреНрдп рд╕реНрдХреНрд░реАрди рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрддрд╛ рд╣реВрдБред рдПрдХ рддрддреНрд╡ iOS рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдФрд░ рдПрдВрдбреНрд░реЙрдЗрдб рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдгрд┐рдд рд╣реИред рд╡реЗ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдмрдЯрди рдХрд╛ рднреА рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВред
public interface MainScreen extends Screen { @Retry(timeout = 20_000L, polling = 2000L) @IOSFindBy(xpath = "//XCUIElementTypeSearchField[@name='Search Wikipedia']") @AndroidFindBy(xpath = "//*[contains(@text, 'Search Wikipedia')]") AtlasMobileElement searchWikipedia(); @IOSFindBy(id = "{{ value }}") AtlasMobileElement button(@Param("value") String value); }
рдЯреЗрд╕реНрдЯ рдПрдХ рдЬреИрд╕реЗ рд▓рдЧрддреЗ рд╣реИрдВ:
public void simpleExample() { onMainScreen().searchWikipedia().click(); onSearchScreen().search().sendKeys("Atlas"); onSearchScreen().item("Atlas LV-3B").swipeDownOn().click(); onArticleScreen().articleTitle().should(allOf(displayed(), text("Atlas LV-3B"))); }
рдКрдкрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо рд╡рд┐рдХрд┐рдкреАрдбрд┐рдпрд╛ рдореБрдЦреНрдп рдкреГрд╖реНрда рдЦреЛрд▓рддреЗ рд╣реИрдВ, рдЦреЛрдЬ рдкрдЯреНрдЯреА рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддреЗ рд╣реИрдВ, рдкрд╛рда рдПрдЯрд▓рд╕ рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВ, рдлрд┐рд░ рд╕реВрдЪреА рдЖрдЗрдЯрдо рдХреЛ рдПрдЯрд▓рд╕ LV-3B рдХреЗ рд╕рд╛рде рд╕реНрдХреНрд░реЙрд▓ рдХрд░реЗрдВ рдФрд░ рдЗрд╕рдХреЗ рджреГрд╢реНрдп рдкрд░ рдЬрд╛рдПрдВред рдЕрдВрддрд┐рдо рдкрдВрдХреНрддрд┐ рдпрд╣ рдЬрд╛рдВрдЪрддреА рд╣реИ рдХрд┐ рд╢реАрд░реНрд╖рдХ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рд╡рд╛рдВрдЫрд┐рдд рдореВрд▓реНрдп рд╢рд╛рдорд┐рд▓ рд╣реИред
рд╢реНрд░реЛрддрд╛рдЗрд╡реЗрдВрдЯ рд▓реЙрдЧрд┐рдВрдЧ рдХреЛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╢реНрд░реЛрддрд╛ (рд╢реНрд░реЛрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдореЗрдВ рдЪрд╛рд░ рдШрдЯрдирд╛рдПрдВ рд╣реЛрддреА рд╣реИрдВ рдЬрдм рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ:
рдкрд╣рд▓реЗ ,
рдкрд╛рд╕ ,
рдЕрд╕рдлрд▓ ред
рдХреЗ рдмрд╛рдж ред

рдЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдиреАрдЪреЗ Allure рд╢реНрд░реЛрддрд╛ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ, рдЬреЛ
рд▓рд┐рдВрдХ рдкрд░ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЖрдЧреЗ, рдПрдЯрд▓рд╕ рдХреНрд▓рд╛рд╕ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рддреЗ рд╕рдордп рд╢реНрд░реЛрддрд╛ рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВред
atlas = new Atlas(new WebDriverConfiguration(driver)).listener(new AllureListener());
рдЙрдкрд░реЛрдХреНрдд рддрд░реАрдХреЗ рд╕реЗ, рд╡рд┐рднрд┐рдиреНрди рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд░рд┐рдкреЛрд░реНрдЯрдкреЛрд░реНрдЯ) рдХреЗ рд▓рд┐рдП рд╢реНрд░реЛрддрд╛ рдмрдирд╛рдирд╛ рд╕рдВрднрд╡ рд╣реИред
рд╕рдВрдмрдВрдз
UI рд╡реЗрдм рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдПрдЯрд▓рд╕-рд╡реЗрдмрдбреНрд░рд╛рдЗрд╡рд░ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдФрд░ рдирд╡реАрдирддрдо рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ (рд╕рдВрд╕реНрдХрд░рдг 1.6.0 рдЗрд╕ рд▓реЗрдЦрди рдХреЗ рд╕рдордп рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ)ред
maven:
<dependency> <groupId>io.qameta.atlas</groupId> <artifactId>atlas-webdriver</artifactId> <version>${atlas.version}</version> </dependency>
Gradle:
dependencies { ompile 'io.qameta.atlas:atlas-webdriver:1.+' }
рдпрджрд┐ рдЖрдк UI рдореЛрдмрд╛рдЗрд▓ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рд╣рдо рднреА рдРрд╕рд╛ рд╣реА рдХрд░рддреЗ рд╣реИрдВред
maven:
<dependency> <groupId>io.qameta.atlas</groupId> <artifactId>atlas-appium</artifactId> <version>${atlas.version}</version> </dependency>
Gradle:
dependencies { ompile 'io.qameta.atlas:atlas-appium:1.+' }
рдХреЗ рдЙрдкрдпреЛрдЧ
рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдирд┐рд░реНрднрд░рддрд╛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдкрдХреЛ рдПрдЯрд▓рд╕ рдХреНрд▓рд╛рд╕ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
@Before public void startDriver() { driver = new ChromeDriver(); atlas = new Atlas(new WebDriverConfiguration(driver)); }
рд╣рдо рдПрдЯрд▓рд╕ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреА рдЖрд╡реГрддреНрддрд┐, рд╕рд╛рде рд╣реА рдЪрд╛рд▓рдХ рдХреЛ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред
рд╡рд░реНрддрдорд╛рди рдореЗрдВ рджреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╣реИрдВ: WebDriverConfiguration рдФрд░ AppiumDriverConfigurationред рдкреНрд░рддреНрдпреЗрдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╣реЛрддреЗ рд╣реИрдВред
рдЕрдЧрд▓рд╛, рд╣рдо рдПрдХ рд╡рд┐рдзрд┐ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рд╕рднреА PageObject рдмрдирд╛рдПрдЧреАред
private <T extends WebPage> T onPage(Class<T> page) { return atlas.create(driver, page); }
рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг:
@Test public void simpleTest() { onPage(MainPage.class).open("https://github.com"); onPage(MainPage.class).header().searchInput().sendKeys("Atlas"); onPage(MainPage.class).header().searchInput().submit(); }
рд╣рдо рд╕рд╛рдЗрдЯ рдЦреЛрд▓рддреЗ рд╣реИрдВ, рд╣реЗрдбрд░ рд▓реЗрдпрд░ рдХреА рдУрд░ рдореБрдбрд╝рддреЗ рд╣реИрдВ, рдЙрд╕рдореЗрдВ рдПрдХ рдЯреЗрдХреНрд╕реНрдЯ рдлреАрд▓реНрдб (рд╕рд░реНрдЪ рдЗрдирдкреБрдЯ) рдЦреЛрдЬрддреЗ рд╣реИрдВ, рдЯреЗрдХреНрд╕реНрдЯ рдПрдВрдЯрд░ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдПрдВрдЯрд░ рджрдмрд╛рддреЗ рд╣реИрдВред
рдкрд░рд┐рдгрд╛рдо
рдЕрдВрдд рдореЗрдВ, рдореИрдВ рдпрд╣ рдиреЛрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдПрдЯрд▓рд╕ рдПрдХ рд▓рдЪреАрд▓рд╛ рдЙрдкрдХрд░рдг рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдорд╣рд╛рди рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВред рдЗрд╕реЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрд░реАрдХреНрд╖рдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдЖрдкрдХреА рдЯреАрдо рдФрд░ рдЖрдкрдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдирд╛, рдЖрджрд┐ред
рд╣рд╛рдЗрдЬреЗрдирдмрдЧ ,
рд╕реЗрд▓реЗрдирд┐рдпрдо рдХреИрдВрдк рдФрд░
рдиреЗрдХреНрд╕рд╛рдЗрди рдХреНрдпреВрдП рдореАрдЯрдЕрдк рдХреА рд░рд┐рдкреЛрд░реНрдЯ
рдХреА рд╡реАрдбрд┐рдпреЛ
рдХреНрд▓рд┐рдк рдЙрдкрд▓рдмреНрдз рд╣реИрдВ ред рдПрдХ рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдЪреИрдЯ @atlashelp рд╣реИред
рдЗрд╕ рдЙрдкрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рдХреЛрдб рдХреА рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (Yandex, SberTech рдФрд░ Tinkoff рдЬреИрд╕реА рдХрдВрдкрдирд┐рдпреЛрдВ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдкрд░ рдкрд░реАрдХреНрд╖рдг)ред