{"id":42118,"date":"2026-05-27T21:01:31","date_gmt":"2026-05-27T18:01:31","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/"},"modified":"2026-05-27T21:01:31","modified_gmt":"2026-05-27T18:01:31","slug":"selenium-ile-temiz-page-object-model-pom-kurulumu","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/","title":{"rendered":"Selenium ile Temiz Page Object Model (POM) Kurulumu"},"content":{"rendered":"<h2>Selenium ile Temiz Page Object Model (POM) Kurulumu<\/h2>\n<p>Web otomasyon testlerinizde karma\u015f\u0131kl\u0131kla m\u0131 bo\u011fu\u015fuyorsunuz? Kodunuz okunmaz hale mi geldi? Selenium ile yazd\u0131\u011f\u0131n\u0131z testlerin s\u00fcrd\u00fcr\u00fclebilirli\u011fi ve yeniden kullan\u0131labilirli\u011fi konusunda endi\u015feleriniz mi var? Bu makale, Selenium ile Java kullanarak temiz ve etkili bir Page Object Model (POM) kurman\u0131n t\u00fcm detaylar\u0131n\u0131 ad\u0131m ad\u0131m a\u00e7\u0131klayarak bu sorunlara \u00e7\u00f6z\u00fcm sunmay\u0131 ama\u00e7l\u0131yor. Okuyucular, POM&#8217;un temel prensiplerinden ba\u015flayarak, ger\u00e7ek d\u00fcnya senaryolar\u0131na uygun, s\u00fcrd\u00fcr\u00fclebilir ve \u00f6l\u00e7eklenebilir otomasyon testleri yazma becerisi kazanacaklar.<\/p>\n<h2 id=\"neden-page-object-model-pom\">Neden Page Object Model (POM) Kullanmal\u0131s\u0131n\u0131z?<\/h2>\n<p>Web otomasyon testleri geli\u015ftirirken, \u00f6zellikle b\u00fcy\u00fck ve karma\u015f\u0131k uygulamalar s\u00f6z konusu oldu\u011funda, kodun y\u00f6netimi ve bak\u0131m\u0131 \u00f6nemli bir zorluk haline gelebilir. Test senaryolar\u0131 artt\u0131k\u00e7a, ayn\u0131 elementleri veya i\u015flemleri tekrar tekrar kodlamak, kod tekrar\u0131na (code duplication) yol a\u00e7ar. Bu durum, bir elementin XPath&#8217;i veya CSS se\u00e7icisi de\u011fi\u015fti\u011finde, bu elementi kullanan t\u00fcm testleri g\u00fcncellemek zorunda kalaca\u011f\u0131n\u0131z anlam\u0131na gelir. Bu da hem zaman kayb\u0131na hem de hata yapma olas\u0131l\u0131\u011f\u0131n\u0131n artmas\u0131na neden olur. \u0130\u015fte tam bu noktada Page Object Model (POM) devreye girer. POM, nesne y\u00f6nelimli programlama (Object-Oriented Programming &#8211; OOP) prensiplerinden yararlanarak, web uygulamas\u0131n\u0131n her bir sayfas\u0131n\u0131 veya \u00f6nemli bir b\u00f6l\u00fcm\u00fcn\u00fc bir Java s\u0131n\u0131f\u0131 olarak temsil eden bir tasar\u0131m desenidir. Bu s\u0131n\u0131flar, o sayfadaki elementleri (butonlar, metin kutular\u0131, linkler vb.) ve bu elementlerle etkile\u015fim kurmak i\u00e7in kullan\u0131lan metotlar\u0131 (t\u0131klama, metin girme, bilgi alma vb.) i\u00e7erir. Yani, bir sayfan\u0131n &#8220;davran\u0131\u015f\u0131n\u0131&#8221; kaps\u00fcller. Bu yakla\u015f\u0131m\u0131n temel avantajlar\u0131 \u015funlard\u0131r:<\/p>\n<ul>\n<li><strong>S\u00fcrd\u00fcr\u00fclebilirlik:<\/strong> Bir web sayfas\u0131ndaki bir elementin konumu (selector) de\u011fi\u015fti\u011finde, bu de\u011fi\u015fikli\u011fi sadece ilgili Page Object s\u0131n\u0131f\u0131nda yapman\u0131z yeterli olur. Bu de\u011fi\u015fiklik, o Page Object&#8217;i kullanan t\u00fcm testlere otomatik olarak yans\u0131r. Bu, bak\u0131m maliyetini \u00f6nemli \u00f6l\u00e7\u00fcde azalt\u0131r.<\/li>\n<li><strong>Yeniden Kullan\u0131labilirlik:<\/strong> Sayfa elementleri ve i\u015flemler, merkezi bir yerde tan\u0131mland\u0131\u011f\u0131 i\u00e7in farkl\u0131 test senaryolar\u0131nda kolayca yeniden kullan\u0131labilir. Bu, kod tekrar\u0131n\u0131 \u00f6nler ve test geli\u015ftirme s\u00fcrecini h\u0131zland\u0131r\u0131r.<\/li>\n<li><strong>Okunabilirlik ve Anla\u015f\u0131l\u0131rl\u0131k:<\/strong> Test kodlar\u0131, sayfa elementlerinin soyutlanmas\u0131 sayesinde daha temiz ve okunabilir hale gelir. Test senaryolar\u0131, sayfa detaylar\u0131ndan ziyade i\u015f mant\u0131\u011f\u0131na odaklan\u0131r. \u00d6rne\u011fin, <code>loginPage.enterUsername(\"kullaniciadi\");<\/code> gibi bir sat\u0131r, <code>driver.findElement(By.id(\"username\")).sendKeys(\"kullaniciadi\");<\/code> gibi bir sat\u0131rdan \u00e7ok daha anlaml\u0131d\u0131r.<\/li>\n<li><strong>Test Kapsam\u0131n\u0131n Artmas\u0131:<\/strong> Kodun daha mod\u00fcler ve y\u00f6netilebilir olmas\u0131, daha fazla test senaryosu yazmay\u0131 ve test kapsam\u0131n\u0131 geni\u015fletmeyi kolayla\u015ft\u0131r\u0131r.<\/li>\n<li><strong>Tak\u0131m \u00c7al\u0131\u015fmas\u0131:<\/strong> Farkl\u0131 geli\u015ftiriciler, uygulaman\u0131n farkl\u0131 sayfalar\u0131n\u0131n Page Object s\u0131n\u0131flar\u0131n\u0131 geli\u015ftirebilir, bu da tak\u0131m \u00e7al\u0131\u015fmas\u0131n\u0131 kolayla\u015ft\u0131r\u0131r ve projelerin daha h\u0131zl\u0131 ilerlemesini sa\u011flar.<\/li>\n<\/ul>\n<p>\u00d6zetle, POM, Selenium ile yap\u0131lan otomasyon testlerinin kalitesini, verimlili\u011fini ve uzun vadeli bak\u0131m\u0131n\u0131 iyile\u015ftiren g\u00fc\u00e7l\u00fc bir tasar\u0131m desenidir. Karma\u015f\u0131k projelerde kodunuzu organize etmenin ve testlerinizi daha profesyonel bir seviyeye ta\u015f\u0131man\u0131n anahtar\u0131d\u0131r.<\/p>\n<h2 id=\"temel-kavramlar-pom-nedir\">POM&#8217;un Temel Kavramlar\u0131 Nelerdir?<\/h2>\n<p>Page Object Model&#8217;i etkin bir \u015fekilde kullanabilmek i\u00e7in baz\u0131 temel kavramlar\u0131 anlamak \u00f6nemlidir. Bu kavramlar, POM&#8217;un yap\u0131s\u0131n\u0131 ve nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 anlamam\u0131za yard\u0131mc\u0131 olacakt\u0131r. Temel olarak POM, web uygulamas\u0131ndaki her bir \u00f6nemli sayfa veya bile\u015fen i\u00e7in ayr\u0131 bir Java s\u0131n\u0131f\u0131 olu\u015fturmaya dayan\u0131r. Bu s\u0131n\u0131flar, &#8220;Page Objects&#8221; olarak adland\u0131r\u0131l\u0131r. Her Page Object s\u0131n\u0131f\u0131, temsil etti\u011fi web sayfas\u0131ndaki belirli elementleri ve bu elementlerle etkile\u015fim kurmak i\u00e7in gereken y\u00f6ntemleri (methods) i\u00e7erir.<\/p>\n<ul>\n<li><strong>Page Object S\u0131n\u0131flar\u0131:<\/strong> Her bir web sayfas\u0131 veya mod\u00fcl i\u00e7in bir Java s\u0131n\u0131f\u0131 olu\u015fturulur. \u00d6rne\u011fin, bir giri\u015f sayfas\u0131 i\u00e7in <code>LoginPage<\/code>, ana sayfa i\u00e7in <code>HomePage<\/code>, \u00fcr\u00fcn arama sayfas\u0131 i\u00e7in <code>SearchPage<\/code> gibi s\u0131n\u0131flar olu\u015fturulabilir. Bu s\u0131n\u0131flar\u0131n amac\u0131, temsil ettikleri sayfan\u0131n yap\u0131s\u0131n\u0131 ve i\u015flevselli\u011fini soyutlamakt\u0131r.<\/li>\n<li><strong>Element Tan\u0131mlamalar\u0131:<\/strong> Her Page Object s\u0131n\u0131f\u0131 i\u00e7inde, temsil etti\u011fi sayfada bulunan web elementleri (butonlar, metin alanlar\u0131, linkler vb.) tan\u0131mlan\u0131r. Bu tan\u0131mlamalar genellikle <code>WebElement<\/code> nesneleri olarak yap\u0131l\u0131r ve elementlerin bulunmas\u0131 i\u00e7in kullan\u0131lan se\u00e7iciler (selectors) ile birlikte belirtilir. Se\u00e7iciler genellikle XPath, CSS Selector, ID, Name gibi stratejilerle belirlenir. \u00d6rne\u011fin, bir giri\u015f sayfas\u0131ndaki kullan\u0131c\u0131 ad\u0131 metin kutusu \u015fu \u015fekilde tan\u0131mlanabilir: <code>@FindBy(id = \"username\") WebElement usernameField;<\/code>. Burada <code>@FindBy<\/code>, PageFactory gibi bir k\u00fct\u00fcphane kullan\u0131ld\u0131\u011f\u0131nda elementin nas\u0131l bulunaca\u011f\u0131n\u0131 belirtir.<\/li>\n<li><strong>Metotlar (Methods):<\/strong> Page Object s\u0131n\u0131flar\u0131 sadece elementleri tan\u0131mlamakla kalmaz, ayn\u0131 zamanda bu elementlerle etkile\u015fim kuracak y\u00f6ntemleri de i\u00e7erir. Bu y\u00f6ntemler, sayfan\u0131n belirli i\u015flevlerini temsil eder. \u00d6rne\u011fin, bir <code>LoginPage<\/code> s\u0131n\u0131f\u0131nda <code>login(String username, String password)<\/code> ad\u0131nda bir metot olabilir. Bu metot, kullan\u0131c\u0131 ad\u0131 ve \u015fifre alanlar\u0131na metin girmeyi ve giri\u015f butonuna t\u0131klamay\u0131 i\u00e7erir. Bu soyutlama sayesinde, test kodlar\u0131 daha okunabilir hale gelir ve sayfa de\u011fi\u015fiklikleri sadece ilgili Page Object s\u0131n\u0131f\u0131nda g\u00fcncellenir.<\/li>\n<li><strong>Driver Nesnesi:<\/strong> Her Page Object s\u0131n\u0131f\u0131, web taray\u0131c\u0131s\u0131n\u0131 kontrol etmek i\u00e7in bir <code>WebDriver<\/code> nesnesine sahip olmal\u0131d\u0131r. Bu nesne, sayfa elementlerini bulmak ve onlarla etkile\u015fim kurmak i\u00e7in kullan\u0131l\u0131r. Genellikle Page Object s\u0131n\u0131flar\u0131n\u0131n constructor&#8217;\u0131 (yap\u0131c\u0131 metodu) arac\u0131l\u0131\u011f\u0131yla <code>WebDriver<\/code> nesnesi bu s\u0131n\u0131flara aktar\u0131l\u0131r.<\/li>\n<li><strong>PageFactory (\u0130ste\u011fe Ba\u011fl\u0131 ama \u00d6nerilir):<\/strong> Selenium&#8217;un PageFactory, Page Object tasar\u0131m desenini uygulamay\u0131 kolayla\u015ft\u0131ran bir yard\u0131mc\u0131 s\u0131n\u0131ft\u0131r. Elementleri <code>@FindBy<\/code> anotasyonlar\u0131 ile tan\u0131mlaman\u0131za olanak tan\u0131r ve <code>PageFactory.initElements(driver, this);<\/code> metodu ile t\u00fcm elementlerin otomatik olarak ba\u015flat\u0131lmas\u0131n\u0131 sa\u011flar. Bu, <code>driver.findElement(...)<\/code> \u00e7a\u011fr\u0131lar\u0131n\u0131 azalt\u0131r ve kodun daha temiz olmas\u0131n\u0131 sa\u011flar.<\/li>\n<\/ul>\n<p>Bu temel kavramlar\u0131 anlad\u0131\u011f\u0131n\u0131zda, POM&#8217;un nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131na dair sa\u011flam bir temel olu\u015fturmu\u015f olursunuz. \u015eimdi bu kavramlar\u0131 pratik uygulamaya d\u00f6kmeye haz\u0131r\u0131z.<\/p>\n<h2 id=\"ilk-pom-yapinizi-kurma\">\u0130lk POM Yap\u0131n\u0131z\u0131 Kurma: Ad\u0131m Ad\u0131m K\u0131lavuz<\/h2>\n<p>Haz\u0131rsan\u0131z, basit bir web sitesi (\u00f6rne\u011fin, bir giri\u015f sayfas\u0131) \u00fczerinde temiz bir Page Object Model yap\u0131s\u0131 kurmaya ba\u015flayal\u0131m. Bu ad\u0131m ad\u0131m rehber, size POM&#8217;u nas\u0131l uygulayaca\u011f\u0131n\u0131z\u0131 g\u00f6sterecektir. \u00d6ncelikle, projenizde a\u015fa\u011f\u0131daki klas\u00f6r yap\u0131s\u0131n\u0131 olu\u015fturman\u0131z\u0131 \u00f6neririm:<\/p>\n<pre><code>\nsrc\/\n\u251c\u2500\u2500 main\/java\/\n\u2502   \u2514\u2500\u2500 com\/example\/pages\/\n\u2502       \u251c\u2500\u2500 BasePage.java\n\u2502       \u251c\u2500\u2500 LoginPage.java\n\u2502       \u2514\u2500\u2500 HomePage.java\n\u2514\u2500\u2500 test\/java\/\n    \u2514\u2500\u2500 com\/example\/tests\/\n        \u2514\u2500\u2500 LoginTest.java\n<\/code><\/pre>\n<p>Bu yap\u0131, sayfa s\u0131n\u0131flar\u0131n\u0131 ve test s\u0131n\u0131flar\u0131n\u0131 ayr\u0131 tutarak projenizi d\u00fczenli tutman\u0131za yard\u0131mc\u0131 olur.<\/p>\n<h3 id=\"ad%C4%B1m-1-temel-sayfa-s%C4%B1n%C4%B1f%C4%B1-basepage\">Ad\u0131m 1: Temel Sayfa S\u0131n\u0131f\u0131 (BasePage)<\/h3>\n<p>T\u00fcm Page Object s\u0131n\u0131flar\u0131n\u0131n ortak \u00f6zelliklerini bar\u0131nd\u0131racak bir <code>BasePage<\/code> s\u0131n\u0131f\u0131 olu\u015fturmak iyi bir pratiktir. Bu s\u0131n\u0131f, t\u00fcm sayfa s\u0131n\u0131flar\u0131 taraf\u0131ndan miras al\u0131nacak (extended) ve WebDriver \u00f6rne\u011fi gibi temel bile\u015fenleri i\u00e7erecektir. Bu, kod tekrar\u0131n\u0131 \u00f6nler ve t\u00fcm sayfa nesnelerinin tutarl\u0131 bir \u015fekilde ba\u015flat\u0131lmas\u0131n\u0131 sa\u011flar.<\/p>\n<pre><code>\npackage com.example.pages;\n\nimport org.openqa.selenium.WebDriver;\nimport org.openqa.selenium.support.PageFactory;\n\npublic class BasePage {\n    protected WebDriver driver;\n\n    public BasePage(WebDriver driver) {\n        this.driver = driver;\n        \/\/ PageFactory'yi kullanarak t\u00fcm @FindBy anotasyonlu elementleri ba\u015flat\u0131r.\n        PageFactory.initElements(driver, this);\n    }\n\n    \/\/ Genel ama\u00e7l\u0131 metotlar eklenebilir, \u00f6rne\u011fin sayfa ba\u015fl\u0131\u011f\u0131n\u0131 alma gibi.\n    public String getPageTitle() {\n        return driver.getTitle();\n    }\n}\n<\/code><\/pre>\n<p>Bu <code>BasePage<\/code> s\u0131n\u0131f\u0131, her Page Object s\u0131n\u0131f\u0131n\u0131n ihtiyac\u0131 olan <code>WebDriver<\/code> \u00f6rne\u011fini al\u0131r ve <code>PageFactory.initElements<\/code> ile elementlerin otomatik olarak ba\u015flat\u0131lmas\u0131n\u0131 sa\u011flar. Ayr\u0131ca, t\u00fcm sayfalarda ortak olarak kullan\u0131labilecek <code>getPageTitle()<\/code> gibi metotlar da burada tan\u0131mlanabilir.<\/p>\n<h3 id=\"ad%C4%B1m-2-giri%C5%9F-sayfas%C4%B1-loginpage\">Ad\u0131m 2: Giri\u015f Sayfas\u0131 (LoginPage)<\/h3>\n<p>\u015eimdi, \u00f6rne\u011fimizdeki giri\u015f sayfas\u0131n\u0131 temsil edecek <code>LoginPage<\/code> s\u0131n\u0131f\u0131n\u0131 olu\u015ftural\u0131m. Bu s\u0131n\u0131f, <code>BasePage<\/code>&#8216;den miras alacak ve giri\u015f sayfas\u0131ndaki elementleri ile giri\u015f i\u015flemini ger\u00e7ekle\u015ftiren metotlar\u0131 i\u00e7erecektir.<\/p>\n<pre><code>\npackage com.example.pages;\n\nimport org.openqa.selenium.WebDriver;\nimport org.openqa.selenium.WebElement;\nimport org.openqa.selenium.support.FindBy;\n\npublic class LoginPage extends BasePage {\n\n    \/\/ Giri\u015f sayfas\u0131ndaki elementleri tan\u0131ml\u0131yoruz.\n    @FindBy(id = \"username\")\n    private WebElement usernameField;\n\n    @FindBy(id = \"password\")\n    private WebElement passwordField;\n\n    @FindBy(xpath = \"\/\/button[@type='submit']\")\n    private WebElement loginButton;\n\n    @FindBy(className = \"error-message\") \/\/ \u00d6rne\u011fin bir hata mesaj\u0131 elementi\n    private WebElement errorMessage;\n\n    \/\/ Constructor, BasePage'in constructor'\u0131n\u0131 \u00e7a\u011f\u0131r\u0131r.\n    public LoginPage(WebDriver driver) {\n        super(driver);\n    }\n\n    \/\/ Kullan\u0131c\u0131 ad\u0131 alan\u0131na metin giren metot.\n    public void enterUsername(String username) {\n        usernameField.sendKeys(username);\n    }\n\n    \/\/ \u015eifre alan\u0131na metin giren metot.\n    public void enterPassword(String password) {\n        passwordField.sendKeys(password);\n    }\n\n    \/\/ Giri\u015f butonuna t\u0131klayan metot.\n    public void clickLoginButton() {\n        loginButton.click();\n    }\n\n    \/\/ Giri\u015f i\u015flemini ger\u00e7ekle\u015ftiren metot.\n    public HomePage login(String username, String password) {\n        enterUsername(username);\n        enterPassword(password);\n        clickLoginButton();\n        \/\/ Giri\u015f ba\u015far\u0131l\u0131 oldu\u011funda ana sayfaya y\u00f6nlendirme beklenir.\n        \/\/ Bu noktada yeni bir HomePage nesnesi d\u00f6nd\u00fcr\u00fcl\u00fcr.\n        return new HomePage(driver);\n    }\n\n    \/\/ Hata mesaj\u0131n\u0131 getiren metot.\n    public String getErrorMessage() {\n        return errorMessage.getText();\n    }\n}\n<\/code><\/pre>\n<p>Bu s\u0131n\u0131fta, <code>@FindBy<\/code> anotasyonlar\u0131 ile elementler tan\u0131mlanm\u0131\u015f ve bu elementlerle etkile\u015fim kurmak i\u00e7in <code>enterUsername<\/code>, <code>enterPassword<\/code>, <code>clickLoginButton<\/code> gibi metotlar olu\u015fturulmu\u015ftur. En \u00f6nemlisi, <code>login<\/code> metodu, t\u00fcm giri\u015f ad\u0131mlar\u0131n\u0131 tek bir \u00e7a\u011fr\u0131da ger\u00e7ekle\u015ftiren bir soyutlama sunar ve ba\u015far\u0131l\u0131 bir giri\u015f sonras\u0131 <code>HomePage<\/code> nesnesini d\u00f6nd\u00fcr\u00fcr.<\/p>\n<h3 id=\"ad%C4%B1m-3-ana-sayfa-homepage\">Ad\u0131m 3: Ana Sayfa (HomePage)<\/h3>\n<p>Giri\u015f yapt\u0131ktan sonra kar\u015f\u0131m\u0131za \u00e7\u0131kacak olan ana sayfay\u0131 temsil eden <code>HomePage<\/code> s\u0131n\u0131f\u0131n\u0131 olu\u015ftural\u0131m. Bu s\u0131n\u0131f da <code>BasePage<\/code>&#8216;den miras alacak ve ana sayfadaki ilgili elementleri ve i\u015flemleri i\u00e7erecektir.<\/p>\n<pre><code>\npackage com.example.pages;\n\nimport org.openqa.selenium.WebDriver;\nimport org.openqa.selenium.WebElement;\nimport org.openqa.selenium.support.FindBy;\n\npublic class HomePage extends BasePage {\n\n    @FindBy(xpath = \"\/\/h1[contains(text(),'Ho\u015f Geldiniz')]\")\n    private WebElement welcomeMessage;\n\n    @FindBy(linkText = \"\u00c7\u0131k\u0131\u015f Yap\")\n    private WebElement logoutLink;\n\n    public HomePage(WebDriver driver) {\n        super(driver);\n    }\n\n    public String getWelcomeMessage() {\n        return welcomeMessage.getText();\n    }\n\n    public void clickLogout() {\n        logoutLink.click();\n    }\n\n    \/\/ Ana sayfaya \u00f6zel ba\u015fka metotlar buraya eklenebilir.\n}\n<\/code><\/pre>\n<p><code>HomePage<\/code> s\u0131n\u0131f\u0131, ana sayfadaki kar\u015f\u0131lama mesaj\u0131n\u0131 ve \u00e7\u0131k\u0131\u015f yap linkini temsil eder. Bu, testlerimizin ana sayfaya ula\u015f\u0131p ula\u015fmad\u0131\u011f\u0131m\u0131z\u0131 do\u011frulamas\u0131n\u0131 veya \u00e7\u0131k\u0131\u015f i\u015flemini ger\u00e7ekle\u015ftirmesini sa\u011flar.<\/p>\n<h3 id=\"ad%C4%B1m-4-test-s%C4%B1n%C4%B1f%C4%B1-logintest\">Ad\u0131m 4: Test S\u0131n\u0131f\u0131 (LoginTest)<\/h3>\n<p>\u015eimdi, olu\u015fturdu\u011fumuz Page Object&#8217;leri kullanarak bir test senaryosu yazal\u0131m. <code>LoginTest<\/code> s\u0131n\u0131f\u0131, Selenium WebDriver&#8217;\u0131 ba\u015flatacak, <code>LoginPage<\/code> nesnesini olu\u015fturacak ve giri\u015f i\u015flemini ger\u00e7ekle\u015ftirecektir. Bu test s\u0131n\u0131f\u0131, Page Object&#8217;lerin nas\u0131l kullan\u0131laca\u011f\u0131n\u0131 g\u00f6steren bir \u00f6rnektir.<\/p>\n<pre><code>\npackage com.example.tests;\n\nimport com.example.pages.HomePage;\nimport com.example.pages.LoginPage;\nimport org.openqa.selenium.WebDriver;\nimport org.openqa.selenium.chrome.ChromeDriver;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterMethod;\nimport org.testng.annotations.BeforeMethod;\nimport org.testng.annotations.Test;\n\nimport java.util.concurrent.TimeUnit;\n\npublic class LoginTest {\n\n    private WebDriver driver;\n    private LoginPage loginPage;\n    private HomePage homePage;\n\n    @BeforeMethod\n    public void setUp() {\n        \/\/ WebDriver'\u0131 ba\u015flat\n        System.setProperty(\"webdriver.chrome.driver\", \"path\/to\/your\/chromedriver\"); \/\/ ChromeDriver yolunu g\u00fcncelleyin\n        driver = new ChromeDriver();\n        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); \/\/ Genel bekleme s\u00fcresi\n        driver.get(\"http:\/\/your-web-app-url.com\/login\"); \/\/ Uygulaman\u0131z\u0131n giri\u015f URL'sini g\u00fcncelleyin\n\n        \/\/ Page Object'leri ba\u015flat\n        loginPage = new LoginPage(driver);\n    }\n\n    @Test\n    public void validLoginTest() {\n        \/\/ LoginPage'deki login metodunu kullanarak giri\u015f yap\n        homePage = loginPage.login(\"testuser\", \"password123\"); \/\/ Ge\u00e7erli kullan\u0131c\u0131 ad\u0131 ve \u015fifre\n\n        \/\/ Giri\u015fin ba\u015far\u0131l\u0131 oldu\u011funu do\u011frula (Ana sayfada kar\u015f\u0131lama mesaj\u0131 gibi)\n        Assert.assertTrue(homePage.getWelcomeMessage().contains(\"Ho\u015f Geldiniz\"), \"Giri\u015f ba\u015far\u0131l\u0131 olmal\u0131yd\u0131.\");\n        Assert.assertEquals(homePage.getPageTitle(), \"Ana Sayfa\", \"Ana sayfa ba\u015fl\u0131\u011f\u0131 yanl\u0131\u015f.\");\n    }\n\n    @Test\n    public void invalidLoginTest() {\n        \/\/ Ge\u00e7ersiz kullan\u0131c\u0131 ad\u0131 ve \u015fifre ile giri\u015f yapmay\u0131 dene\n        loginPage.enterUsername(\"invaliduser\");\n        loginPage.enterPassword(\"wrongpassword\");\n        loginPage.clickLoginButton();\n\n        \/\/ Hata mesaj\u0131n\u0131n g\u00f6r\u00fcnd\u00fc\u011f\u00fcn\u00fc do\u011frula\n        Assert.assertTrue(loginPage.getErrorMessage().contains(\"Ge\u00e7ersiz kullan\u0131c\u0131 ad\u0131 veya \u015fifre\"), \"Hata mesaj\u0131 g\u00f6r\u00fcnmeliydi.\");\n    }\n\n    @AfterMethod\n    public void tearDown() {\n        \/\/ WebDriver'\u0131 kapat\n        if (driver != null) {\n            driver.quit();\n        }\n    }\n}\n<\/code><\/pre>\n<p>Bu test s\u0131n\u0131f\u0131nda, <code>@BeforeMethod<\/code> ile her testten \u00f6nce WebDriver ba\u015flat\u0131l\u0131r ve giri\u015f URL&#8217;sine gidilir. Ard\u0131ndan <code>LoginPage<\/code> nesnesi olu\u015fturulur. <code>validLoginTest<\/code> metodu, <code>loginPage.login()<\/code> metodunu kullanarak giri\u015f yapar ve <code>HomePage<\/code> nesnesini al\u0131r. Sonras\u0131nda, <code>HomePage<\/code>&#8216;den al\u0131nan kar\u015f\u0131lama mesaj\u0131 ile giri\u015fin ba\u015far\u0131l\u0131 olup olmad\u0131\u011f\u0131 do\u011frulan\u0131r. <code>invalidLoginTest<\/code> metodu ise ge\u00e7ersiz bilgilerle giri\u015f yapmay\u0131 dener ve beklenen hata mesaj\u0131n\u0131n g\u00f6r\u00fcnd\u00fc\u011f\u00fcn\u00fc kontrol eder. Son olarak, <code>@AfterMethod<\/code> ile her testten sonra WebDriver kapat\u0131l\u0131r.<\/p>\n<h2 id=\"ger%C3%A7ek-d%C3%BCnya-senaryolar%C4%B1-ve-vaka-analizleri\">Ger\u00e7ek D\u00fcnya Senaryolar\u0131 ve Vaka Analizleri<\/h2>\n<p>Yukar\u0131daki temel kurulum, POM&#8217;un nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 g\u00f6stermektedir. Ancak ger\u00e7ek d\u00fcnya uygulamalar\u0131 genellikle daha karma\u015f\u0131kt\u0131r ve farkl\u0131 senaryolarla kar\u015f\u0131la\u015f\u0131r\u0131z. Bu b\u00f6l\u00fcmde, daha geli\u015fmi\u015f POM uygulamalar\u0131n\u0131 ve s\u0131k kar\u015f\u0131la\u015f\u0131lan durumlar\u0131 ele alaca\u011f\u0131z.<\/p>\n<h3 id=\"karma%C5%9F%C4%B1k-sayfalar%C4%B1-y%C3%B6netme\">Karma\u015f\u0131k Sayfalar\u0131 Y\u00f6netme<\/h3>\n<p>Baz\u0131 web sayfalar\u0131 olduk\u00e7a karma\u015f\u0131k olabilir, bir\u00e7ok b\u00f6l\u00fcm\u00fc ve i\u00e7 i\u00e7e ge\u00e7mi\u015f elementleri bar\u0131nd\u0131rabilir. Bu t\u00fcr durumlarda, tek bir b\u00fcy\u00fck Page Object s\u0131n\u0131f\u0131 yerine, sayfay\u0131 daha k\u00fc\u00e7\u00fck, y\u00f6netilebilir par\u00e7alara ay\u0131rmak faydal\u0131 olacakt\u0131r. \u00d6rne\u011fin, bir e-ticaret sitesinin \u00fcr\u00fcn detay sayfas\u0131nda, \u00fcr\u00fcn bilgileri, resim galerisi, yorumlar b\u00f6l\u00fcm\u00fc ve &#8220;sepete ekle&#8221; butonu gibi farkl\u0131 b\u00f6l\u00fcmler olabilir. Bu b\u00f6l\u00fcmler i\u00e7in ayr\u0131 &#8220;komponent&#8221; s\u0131n\u0131flar\u0131 olu\u015fturabiliriz.<\/p>\n<p><strong>Vaka Analizi: E-ticaret Sitesi \u00dcr\u00fcn Detay Sayfas\u0131<\/strong><\/p>\n<p>Diyelim ki bir \u00fcr\u00fcn detay sayfas\u0131n\u0131 test ediyoruz. Bu sayfada \u015funlar bulunuyor:<\/p>\n<ul>\n<li>\u00dcr\u00fcn Ad\u0131, Fiyat\u0131, A\u00e7\u0131klamas\u0131<\/li>\n<li>\u00dcr\u00fcn Resimleri (bir galeri i\u00e7inde)<\/li>\n<li>Miktar Se\u00e7ici<\/li>\n<li>&#8220;Sepete Ekle&#8221; Butonu<\/li>\n<li>\u00dcr\u00fcn Yorumlar\u0131 B\u00f6l\u00fcm\u00fc<\/li>\n<\/ul>\n<p>Bu sayfay\u0131 y\u00f6netmek i\u00e7in \u015fu yap\u0131y\u0131 d\u00fc\u015f\u00fcnebiliriz:<\/p>\n<pre><code>\n\/\/ Ana sayfa nesnesi\npublic class ProductDetailsPage extends BasePage {\n    \/\/ ...\n    \/\/ \u00dcr\u00fcn bilgileri b\u00f6l\u00fcm\u00fc i\u00e7in ayr\u0131 bir s\u0131n\u0131f\n    @FindBy(css = \".product-info-section\")\n    private WebElement productInfoSectionElement;\n    private ProductInfoComponent productInfoComponent;\n\n    \/\/ Resim galerisi i\u00e7in ayr\u0131 bir s\u0131n\u0131f\n    @FindBy(css = \".image-gallery\")\n    private WebElement imageGalleryElement;\n    private ImageGalleryComponent imageGalleryComponent;\n\n    \/\/ Sepete ekle butonu\n    @FindBy(id = \"add-to-cart-button\")\n    private WebElement addToCartButton;\n\n    public ProductDetailsPage(WebDriver driver) {\n        super(driver);\n        \/\/ Komponentleri de ba\u015flat\n        productInfoComponent = new ProductInfoComponent(productInfoSectionElement);\n        imageGalleryComponent = new ImageGalleryComponent(imageGalleryElement);\n    }\n\n    public void clickAddToCart() {\n        addToCartButton.click();\n    }\n\n    \/\/ Komponent metotlar\u0131n\u0131 kullan\n    public String getProductName() {\n        return productInfoComponent.getProductName();\n    }\n\n    public void selectQuantity(int quantity) {\n        \/\/ Miktar se\u00e7ici ile ilgili i\u015flemler\n    }\n    \/\/ ... di\u011fer metotlar\n}\n\n\/\/ \u00dcr\u00fcn bilgileri b\u00f6l\u00fcm\u00fc i\u00e7in komponent s\u0131n\u0131f\u0131\npublic class ProductInfoComponent {\n    private WebElement element;\n\n    @FindBy(css = \"h1.product-title\")\n    private WebElement productName;\n    @FindBy(css = \".product-price\")\n    private WebElement productPrice;\n\n    public ProductInfoComponent(WebElement element) {\n        this.element = element;\n        \/\/ Komponentin kendi elementleri i\u00e7in de PageFactory kullan\u0131labilir\n        PageFactory.initElements(new org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory(element), this);\n    }\n\n    public String getProductName() {\n        return productName.getText();\n    }\n\n    public String getProductPrice() {\n        return productPrice.getText();\n    }\n}\n\n\/\/ Resim galerisi i\u00e7in komponent s\u0131n\u0131f\u0131\npublic class ImageGalleryComponent {\n    private WebElement element;\n\n    @FindBy(css = \".main-image\")\n    private WebElement mainImage;\n    @FindBy(css = \".thumbnail\")\n    private List<WebElement> thumbnails;\n\n    public ImageGalleryComponent(WebElement element) {\n        this.element = element;\n        PageFactory.initElements(new org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory(element), this);\n    }\n\n    public void clickThumbnail(int index) {\n        if (index >= 0 && index < thumbnails.size()) {\n            thumbnails.get(index).click();\n        }\n    }\n\n    public String getMainImageSrc() {\n        return mainImage.getAttribute(\"src\");\n    }\n}\n<\/code><\/pre>\n<p>Bu yakla\u015f\u0131mda, <code>ProductDetailsPage<\/code> ana sayfa nesnesi olarak kal\u0131rken, <code>ProductInfoComponent<\/code> ve <code>ImageGalleryComponent<\/code> gibi s\u0131n\u0131flar, sayfan\u0131n belirli b\u00f6l\u00fcmlerini y\u00f6netir. Bu, kodun daha mod\u00fcler, anla\u015f\u0131l\u0131r ve bak\u0131m\u0131 daha kolay olmas\u0131n\u0131 sa\u011flar. Her komponent, kendi i\u00e7indeki elementleri ve etkile\u015fimleri y\u00f6netir.<\/p>\n<h3 id=\"dinamik-elementler-ve-beklemeler\">Dinamik Elementler ve Beklemeler<\/h3>\n<p>Web uygulamalar\u0131 genellikle dinamik i\u00e7eriklere sahiptir. Elementler sayfa y\u00fcklendi\u011finde hemen g\u00f6r\u00fcnmeyebilir, JavaScript ile sonradan y\u00fcklenebilir veya belirli bir s\u00fcre sonra kaybolabilir. Bu durumlar i\u00e7in Selenium'da beklemeler (waits) kullanmak kritiktir. POM'da bu beklemeleri Page Object s\u0131n\u0131flar\u0131n\u0131n i\u00e7ine entegre etmek, testlerin daha kararl\u0131 olmas\u0131n\u0131 sa\u011flar.<\/p>\n<ul>\n<li><strong>Implicit Wait (\u00d6rt\u00fcl\u00fc Bekleme):<\/strong> <code>driver.manage().timeouts().implicitlyWait(seconds, TimeUnit.SECONDS);<\/code> ile tan\u0131mlan\u0131r. Belirtilen s\u00fcre boyunca WebDriver, bir elementi bulamazsa bekler. Bu, t\u00fcm elementler i\u00e7in ge\u00e7erlidir ve genellikle <code>@BeforeMethod<\/code> veya test ba\u015flang\u0131c\u0131nda bir kere ayarlan\u0131r.<\/li>\n<li><strong>Explicit Wait (A\u00e7\u0131k Bekleme):<\/strong> Belirli bir ko\u015ful sa\u011flanana kadar beklemeyi sa\u011flar. Bu, daha kontroll\u00fc ve g\u00fcvenilirdir. <code>WebDriverWait<\/code> ve <code>ExpectedConditions<\/code> s\u0131n\u0131flar\u0131 ile kullan\u0131l\u0131r.<\/li>\n<\/ul>\n<p>POM i\u00e7inde Explicit Wait kullan\u0131m\u0131:<\/p>\n<pre><code>\npackage com.example.pages;\n\nimport org.openqa.selenium.WebDriver;\nimport org.openqa.selenium.WebElement;\nimport org.openqa.selenium.support.FindBy;\nimport org.openqa.selenium.support.ui.ExpectedConditions;\nimport org.openqa.selenium.support.ui.WebDriverWait;\n\nimport java.time.Duration;\n\npublic class LoginPage extends BasePage {\n\n    @FindBy(id = \"username\")\n    private WebElement usernameField;\n\n    @FindBy(id = \"password\")\n    private WebElement passwordField;\n\n    @FindBy(xpath = \"\/\/button[@type='submit']\")\n    private WebElement loginButton;\n\n    public LoginPage(WebDriver driver) {\n        super(driver);\n    }\n\n    public void enterUsername(String username) {\n        \/\/ Kullan\u0131c\u0131 ad\u0131 alan\u0131 g\u00f6r\u00fcnene kadar bekle\n        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); \/\/ 10 saniye bekle\n        WebElement element = wait.until(ExpectedConditions.visibilityOf(usernameField));\n        element.sendKeys(username);\n    }\n\n    public void clickLoginButton() {\n        \/\/ Giri\u015f butonu t\u0131klanabilir olana kadar bekle\n        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));\n        WebElement element = wait.until(ExpectedConditions.elementToBeClickable(loginButton));\n        element.click();\n    }\n\n    \/\/ ... di\u011fer metotlar\n}\n<\/code><\/pre>\n<p>Bu \u00f6rnekte, <code>enterUsername<\/code> ve <code>clickLoginButton<\/code> metotlar\u0131, ilgili elementler g\u00f6r\u00fcnene veya t\u0131klanabilir hale gelene kadar beklemek i\u00e7in <code>WebDriverWait<\/code> kullan\u0131r. Bu, testlerin kararl\u0131l\u0131\u011f\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131r\u0131r, \u00f6zellikle a\u011f yava\u015fl\u0131\u011f\u0131 veya sunucu yan\u0131t s\u00fcrelerindeki dalgalanmalar durumunda.<\/p>\n<h3 id=\"veri-s%C3%BCr%C3%BCkl%C3%BC-testler-data-driven-testing-i%C3%A7in-pom\">Veri S\u00fcr\u00fckl\u00fc Testler (Data-Driven Testing) i\u00e7in POM<\/h3>\n<p>Veri s\u00fcr\u00fckl\u00fc testler (Data-Driven Testing), ayn\u0131 test senaryosunu farkl\u0131 veri setleriyle \u00e7al\u0131\u015ft\u0131rmay\u0131 i\u00e7erir. POM, bu t\u00fcr testleri desteklemek i\u00e7in idealdir. Test s\u0131n\u0131flar\u0131, veriyi bir d\u0131\u015f kaynaktan (CSV, Excel, veritaban\u0131 vb.) okuyabilir ve bu veriyi Page Object metotlar\u0131na arg\u00fcman olarak ge\u00e7irebilir.<\/p>\n<p>\u00d6rne\u011fin, bir giri\u015f testini farkl\u0131 kullan\u0131c\u0131 adlar\u0131 ve \u015fifrelerle \u00e7al\u0131\u015ft\u0131rmak isteyebilirsiniz. Test s\u0131n\u0131f\u0131n\u0131zda veriyi okuyup, her bir veri seti i\u00e7in <code>loginPage.login()<\/code> metodunu \u00e7a\u011f\u0131rabilirsiniz.<\/p>\n<pre><code>\n@Test(dataProvider = \"loginData\")\npublic void multipleLoginsTest(String username, String password, boolean expectedSuccess) {\n    HomePage homePage = loginPage.login(username, password);\n\n    if (expectedSuccess) {\n        Assert.assertTrue(homePage.getWelcomeMessage().contains(\"Ho\u015f Geldiniz\"), \"Giri\u015f ba\u015far\u0131l\u0131 olmal\u0131yd\u0131.\");\n    } else {\n        \/\/ Hata durumunu kontrol et\n        Assert.assertTrue(loginPage.getErrorMessage().contains(\"Ge\u00e7ersiz\"), \"Hata mesaj\u0131 bekleniyordu.\");\n    }\n}\n\n@DataProvider(name = \"loginData\")\npublic Object[][] getLoginData() {\n    \/\/ Buraya CSV, Excel veya hardcoded veriler eklenebilir\n    return new Object[][] {\n        {\"validuser1\", \"pass1\", true},\n        {\"invaliduser\", \"wrongpass\", false},\n        {\"validuser2\", \"pass2\", true}\n    };\n}\n<\/code><\/pre>\n<p>Bu \u00f6rnekte, TestNG'nin <code>@DataProvider<\/code> \u00f6zelli\u011fi kullan\u0131larak giri\u015f verileri sa\u011flan\u0131r. Her bir veri seti i\u00e7in <code>multipleLoginsTest<\/code> metodu \u00e7al\u0131\u015f\u0131r ve <code>loginPage.login()<\/code> metodu bu verilerle \u00e7a\u011fr\u0131l\u0131r. Bu, testlerinizi daha esnek ve kapsaml\u0131 hale getirir.<\/p>\n<h2 id=\"ileri-d%C3%BCzey-ipular%C4%B1-ve-p%C3%BCf-noktalar%C4%B1\">\u0130leri D\u00fczey \u0130pu\u00e7lar\u0131 ve P\u00fcf Noktalar\u0131<\/h2>\n<p>POM'u daha etkili kullanman\u0131za yard\u0131mc\u0131 olacak baz\u0131 ileri d\u00fczey ipu\u00e7lar\u0131 ve yayg\u0131n olarak kar\u015f\u0131la\u015f\u0131lan sorunlara \u00e7\u00f6z\u00fcmler:<\/p>\n<ul>\n<li><strong>Sabitleri (Constants) Kullanma:<\/strong> URL'ler, kullan\u0131c\u0131 adlar\u0131, \u015fifreler gibi tekrar eden de\u011ferleri do\u011frudan kod i\u00e7ine yazmak yerine, sabitler (constants) olarak tan\u0131mlay\u0131n. Bunlar\u0131 <code>BasePage<\/code>'de veya ayr\u0131 bir <code>Constants<\/code> s\u0131n\u0131f\u0131nda saklayabilirsiniz. Bu, de\u011ferleri tek bir yerden g\u00fcncellemenizi kolayla\u015ft\u0131r\u0131r.<\/li>\n<li><strong>Enum'lar ile Durum Y\u00f6netimi:<\/strong> Baz\u0131 durumlarda, bir sayfan\u0131n farkl\u0131 durumlar\u0131 olabilir (\u00f6rne\u011fin, bir \u00fcr\u00fcn sepette var veya yok). Bu durumlar\u0131 y\u00f6netmek i\u00e7in Enum'lar (enumerations) kullanmak kodu daha okunabilir hale getirebilir.<\/li>\n<li><strong>Hata Y\u00f6netimi ve Raporlama:<\/strong> POM s\u0131n\u0131flar\u0131na, olas\u0131 hatalar\u0131 yakalayan ve raporlama ara\u00e7lar\u0131na (\u00f6rne\u011fin, ExtentReports, Allure Reports) bilgi g\u00f6nderen metotlar ekleyebilirsiniz. \u00d6rne\u011fin, bir element bulunamad\u0131\u011f\u0131nda veya bir i\u015flem ba\u015far\u0131s\u0131z oldu\u011funda ekran g\u00f6r\u00fcnt\u00fcs\u00fc al\u0131p raporlayabilirsiniz.<\/li>\n<li><strong>Test Verisi Y\u00f6netimi:<\/strong> B\u00fcy\u00fck projelerde test verilerini y\u00f6netmek \u00f6nemlidir. Veri tabanlar\u0131, harici dosyalar (Excel, JSON, YAML) veya test veri y\u00f6netim ara\u00e7lar\u0131 kullanarak verilerinizi merkezi bir yerde saklay\u0131n ve POM s\u0131n\u0131flar\u0131n\u0131za eri\u015filebilir hale getirin.<\/li>\n<li><strong>Mod\u00fclerlik ve Tek Sorumluluk Prensibi (SRP):<\/strong> Her Page Object s\u0131n\u0131f\u0131n\u0131n yaln\u0131zca bir sorumlulu\u011fu olmal\u0131d\u0131r: temsil etti\u011fi sayfan\u0131n veya bile\u015fenin elementlerini ve davran\u0131\u015flar\u0131n\u0131 y\u00f6netmek. Bir s\u0131n\u0131f \u00e7ok fazla i\u015f yapmaya ba\u015flad\u0131\u011f\u0131nda, onu daha k\u00fc\u00e7\u00fck, daha odakl\u0131 s\u0131n\u0131flara b\u00f6lmeyi d\u00fc\u015f\u00fcn\u00fcn.<\/li>\n<li><strong>Soyutlama Seviyesi:<\/strong> POM'un amac\u0131 soyutlamad\u0131r. Test kodunuzun, hangi elementlerin nas\u0131l bulundu\u011funa dair detaylar\u0131 bilmemesi gerekir. Testler, sayfan\u0131n ne yapt\u0131\u011f\u0131n\u0131 anlamal\u0131, nas\u0131l yapt\u0131\u011f\u0131n\u0131 de\u011fil. \u00d6rne\u011fin, <code>loginPage.login(\"user\", \"pass\")<\/code> demek, testin amac\u0131n\u0131 net bir \u015fekilde ifade eder.<\/li>\n<li><strong>Sayfa Y\u00fcklenmesini Bekleme:<\/strong> Her Page Object'in constructor'\u0131nda veya ilgili metotlar\u0131nda, sayfan\u0131n tamamen y\u00fcklenmesini sa\u011flamak i\u00e7in uygun beklemeleri (Explicit Waits) kullan\u0131n. Bu, testlerin kararl\u0131l\u0131\u011f\u0131n\u0131 art\u0131r\u0131r.<\/li>\n<li><strong>Page Factory Alternatifleri:<\/strong> Page Factory harika bir ara\u00e7 olsa da, baz\u0131 durumlarda (\u00f6rne\u011fin, dinamik elementler veya karma\u015f\u0131k DOM yap\u0131lar\u0131) manuel element bulma (<code>driver.findElement()<\/code>) daha esnek olabilir. Ancak, <code>PageFactory.initElements()<\/code> kullanmak, kodunuzu daha temiz tutman\u0131n en iyi yollar\u0131ndan biridir.<\/li>\n<li><strong>Framework Entegrasyonu:<\/strong> POM'u JUnit, TestNG gibi test framework'leri ve Maven, Gradle gibi build ara\u00e7lar\u0131yla entegre etmek, projenizin daha profesyonel ve y\u00f6netilebilir olmas\u0131n\u0131 sa\u011flar.<\/li>\n<\/ul>\n<p>Bu ipu\u00e7lar\u0131, POM'u sadece bir tasar\u0131m deseni olmaktan \u00e7\u0131kar\u0131p, ger\u00e7ek d\u00fcnya otomasyon projelerinizde g\u00fc\u00e7l\u00fc bir ara\u00e7 haline getirmenize yard\u0131mc\u0131 olacakt\u0131r.<\/p>\n<h2 id=\"sonu%C3%A7-ve-s%C4%B1k%C3%A7a-sorulan-sorular\">Sonu\u00e7 ve S\u0131k\u00e7a Sorulan Sorular<\/h2>\n<p>Selenium ile temiz bir Page Object Model (POM) kurmak, otomasyon testlerinizin s\u00fcrd\u00fcr\u00fclebilirli\u011fini, okunabilirli\u011fini ve yeniden kullan\u0131labilirli\u011fini \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131r\u0131r. Bu makalede, POM'un temel prensiplerini, ad\u0131m ad\u0131m kurulumunu, karma\u015f\u0131k senaryolar\u0131 y\u00f6netme y\u00f6ntemlerini ve ileri d\u00fczey ipu\u00e7lar\u0131n\u0131 ele ald\u0131k. Temel <code>BasePage<\/code> s\u0131n\u0131f\u0131ndan ba\u015flayarak, \u00f6zel sayfa s\u0131n\u0131flar\u0131 (<code>LoginPage<\/code>, <code>HomePage<\/code>) olu\u015fturmay\u0131 ve bu s\u0131n\u0131flar\u0131 test senaryolar\u0131nda nas\u0131l kullanaca\u011f\u0131m\u0131z\u0131 g\u00f6rd\u00fck. Ayr\u0131ca, dinamik elementleri y\u00f6netmek ve veri s\u00fcr\u00fckl\u00fc testler i\u00e7in POM'u nas\u0131l uyarlayaca\u011f\u0131m\u0131z\u0131 da inceledik.<\/p>\n<p>POM'u benimsemek, ba\u015flang\u0131\u00e7ta biraz daha fazla \u00e7aba gerektirse de, uzun vadede test otomasyon projelerinizin ba\u015far\u0131s\u0131 i\u00e7in kritik \u00f6neme sahiptir. Kodunuz daha d\u00fczenli, daha az hataya a\u00e7\u0131k ve gelecekteki de\u011fi\u015fikliklere daha kolay adapte olabilir hale gelecektir. Bu da geli\u015ftirme s\u00fcre\u00e7lerinizi h\u0131zland\u0131racak ve otomasyon testlerinizden alaca\u011f\u0131n\u0131z verimi art\u0131racakt\u0131r.<\/p>\n<h3 id=\"s%C4%B1k%C3%A7a-sorulan-sorular-sss\">S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<ul>\n<li>\n            <strong>S: POM'u kullanmak i\u00e7in hangi Java bilmem gerekiyor?<\/strong><br \/>\n            C: Temel Java bilgisi yeterlidir. Nesne y\u00f6nelimli programlama (s\u0131n\u0131flar, nesneler, miras alma), metodlar ve de\u011fi\u015fkenler gibi kavramlara hakim olman\u0131z POM'u anlaman\u0131z ve uygulaman\u0131z i\u00e7in yeterli olacakt\u0131r.\n        <\/li>\n<li>\n            <strong>S: Bir web sayfas\u0131nda \u00e7ok fazla element varsa ne yapmal\u0131y\u0131m?<\/strong><br \/>\n            C: Bu durumda sayfay\u0131 daha k\u00fc\u00e7\u00fck, mant\u0131ksal bile\u015fenlere ay\u0131rarak ayr\u0131 komponent s\u0131n\u0131flar\u0131 olu\u015fturabilirsiniz. Bu, ana Page Object s\u0131n\u0131f\u0131n\u0131 daha y\u00f6netilebilir tutar.\n        <\/li>\n<li>\n            <strong>S: POM ile testlerimin h\u0131z\u0131 artar m\u0131?<\/strong><br \/>\n            C: POM do\u011frudan test h\u0131z\u0131n\u0131 art\u0131rmaz, ancak kodun daha temiz ve bak\u0131m\u0131 kolay olmas\u0131 sayesinde test geli\u015ftirme ve hata ay\u0131klama s\u00fcre\u00e7lerini h\u0131zland\u0131r\u0131r. Ayr\u0131ca, do\u011fru beklemelerin (Explicit Waits) kullan\u0131lmas\u0131, testlerin kararl\u0131l\u0131\u011f\u0131n\u0131 art\u0131rarak gereksiz bekleme s\u00fcrelerini azalt\u0131r.\n        <\/li>\n<li>\n            <strong>S: POM'u ba\u015fka otomasyon ara\u00e7lar\u0131yla da kullanabilir miyim?<\/strong><br \/>\n            C: Evet, POM, web otomasyonunda yayg\u0131n olarak kullan\u0131lan bir tasar\u0131m desenidir ve Selenium d\u0131\u015f\u0131ndaki ara\u00e7larla (\u00f6rne\u011fin, Playwright, Cypress) da uygulanabilir. Temel prensipler ayn\u0131d\u0131r.\n        <\/li>\n<li>\n            <strong>S: Her sayfa i\u00e7in ayr\u0131 bir s\u0131n\u0131f m\u0131 olu\u015fturmal\u0131y\u0131m?<\/strong><br \/>\n            C: Genellikle evet, uygulaman\u0131zdaki her ana sayfa veya \u00f6nemli bir mod\u00fcl i\u00e7in ayr\u0131 bir Page Object s\u0131n\u0131f\u0131 olu\u015fturmak iyi bir pratiktir. Ancak, \u00e7ok k\u00fc\u00e7\u00fck veya sadece birka\u00e7 element i\u00e7eren sayfalar i\u00e7in bu gerekli olmayabilir.\n        <\/li>\n<\/ul>\n<p>#Selenium #PageObjectModel #Java #WebOtomasyon #TestOtomasyonu #YazilimTesti<\/p>\n","protected":false},"excerpt":{"rendered":"Web otomasyon testlerinizde karma\u015f\u0131kl\u0131kla m\u0131 bo\u011fu\u015fuyorsunuz? Kodunuz okunmaz hale mi geldi?","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-42118","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Selenium ile Temiz Page Object Model (POM) Kurulumu - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Selenium ile Temiz Page Object Model (POM) Kurulumu\" \/>\n<meta property=\"og:description\" content=\"Web otomasyon testlerinizde karma\u015f\u0131kl\u0131kla m\u0131 bo\u011fu\u015fuyorsunuz? Kodunuz okunmaz hale mi geldi?\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2026-05-27T18:01:31+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"21 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Selenium ile Temiz Page Object Model (POM) Kurulumu\",\"datePublished\":\"2026-05-27T18:01:31+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/\"},\"wordCount\":3044,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/#respond\"]}],\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/\",\"name\":\"Selenium ile Temiz Page Object Model (POM) Kurulumu - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2026-05-27T18:01:31+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Selenium ile Temiz Page Object Model (POM) Kurulumu\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Selenium ile Temiz Page Object Model (POM) Kurulumu - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/","og_locale":"tr_TR","og_type":"article","og_title":"Selenium ile Temiz Page Object Model (POM) Kurulumu","og_description":"Web otomasyon testlerinizde karma\u015f\u0131kl\u0131kla m\u0131 bo\u011fu\u015fuyorsunuz? Kodunuz okunmaz hale mi geldi?","og_url":"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2026-05-27T18:01:31+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"21 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Selenium ile Temiz Page Object Model (POM) Kurulumu","datePublished":"2026-05-27T18:01:31+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/"},"wordCount":3044,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/#respond"]}],"copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/","url":"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/","name":"Selenium ile Temiz Page Object Model (POM) Kurulumu - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2026-05-27T18:01:31+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/selenium-ile-temiz-page-object-model-pom-kurulumu\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Selenium ile Temiz Page Object Model (POM) Kurulumu"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/42118","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=42118"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/42118\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=42118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=42118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=42118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}