diff --git a/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.en.md b/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.en.md index 648d76f3d4be..5ce6b57683a6 100644 --- a/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.en.md +++ b/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.en.md @@ -198,13 +198,15 @@ requests from the test. ## Page Component Objects A page object does not necessarily need to represent all the parts of a -page itself. The same principles used for page objects can be used to -create "Page _Component_ Objects" that represent discrete chunks of the -page and can be included in page objects. These component objects can +page itself. This was [noted by Martin Fowler](https://martinfowler.com/bliki/PageObject.html#footnote-panel-object) in the early days, while first coining the term "panel objects". + +The same principles used for page objects can be used to +create "Page _Component_ Objects", as it was later called, that represent discrete chunks of the +page and **can be included in page objects**. These component objects can provide references to the elements inside those discrete chunks, and -methods to leverage the functionality provided by them. +methods to leverage the functionality or behavior provided by them. -For example, a Product page has multiple products. +For example, a Products page has multiple products. ```html @@ -242,7 +244,7 @@ Each product is a component of the Products page. ``` -The Product page HAS-A list of products. This relationship is called Composition. In simpler terms, something is _composed of_ another thing. +The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is _composed of_ another thing. ```java public abstract class BasePage { @@ -325,7 +327,7 @@ So now, the products test would use the page object and the page component objec public class ProductsTest { @Test public void testProductInventory() { - var productsPage = new ProductsPage(driver); + var productsPage = new ProductsPage(driver); // page object var products = productsPage.getProducts(); assertEquals(6, products.size()); // expected, actual } @@ -336,7 +338,7 @@ public class ProductsTest { // Pass a lambda expression (predicate) to filter the list of products // The predicate or "strategy" is the behavior passed as parameter - var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); + var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light")); assertEquals(new BigDecimal("29.99"), backpack.getPrice()); @@ -354,8 +356,7 @@ components used throughout the site (e.g. a navigation bar), then it may improve maintainability and reduce code duplication. ## Other Design Patterns Used in Testing -There are other design patterns that also may be used in testing. Some use a -Page Factory for instantiating their page objects. Discussing all of these is +There are other design patterns that also may be used in testing. Discussing all of these is beyond the scope of this user guide. Here, we merely want to introduce the concepts to make the reader aware of some of the things that can be done. As was mentioned earlier, many have blogged on this topic and we encourage the @@ -366,11 +367,11 @@ reader to search for blogs on these topics. PageObjects can be thought of as facing in two directions simultaneously. Facing toward the developer of a test, they represent the **services** offered by a particular page. Facing away from the developer, they should be the only thing that has a deep knowledge of the structure of the HTML of a page (or part of a page) It's simplest to think of the methods on a Page Object as offering the "services" that a page offers rather than exposing the details and mechanics of the page. As an example, think of the inbox of any web-based email system. Amongst the services it offers are the ability to compose a new email, choose to read a single email, and list the subject lines of the emails in the inbox. How these are implemented shouldn't matter to the test. -Because we're encouraging the developer of a test to try and think about the services they're interacting with rather than the implementation, PageObjects should seldom expose the underlying WebDriver instance. To facilitate this, methods on the PageObject should return other PageObjects. This means we can effectively model the user's journey through our application. It also means that should the way that pages relate to one another change (like when the login page asks the user to change their password the first time they log into a service when it previously didn't do that), simply changing the appropriate method's signature will cause the tests to fail to compile. Put another way; we can tell which tests would fail without needing to run them when we change the relationship between pages and reflect this in the PageObjects. +Because we're encouraging the developer of a test to try and think about the services they're interacting with rather than the implementation, PageObjects should seldom expose the underlying WebDriver instance. To facilitate this, **methods on the PageObject should return other PageObjects**. This means we can effectively model the user's journey through our application. It also means that should the way that pages relate to one another change (like when the login page asks the user to change their password the first time they log into a service when it previously didn't do that), simply changing the appropriate method's signature will cause the tests to fail to compile. Put another way; we can tell which tests would fail without needing to run them when we change the relationship between pages and reflect this in the PageObjects. One consequence of this approach is that it may be necessary to model (for example) both a successful and unsuccessful login; or a click could have a different result depending on the app's state. When this happens, it is common to have multiple methods on the PageObject: -``` +```java public class LoginPage { public HomePage loginAs(String username, String password) { // ... clever magic happens here @@ -388,7 +389,7 @@ public class LoginPage { The code presented above shows an important point: the tests, not the PageObjects, should be responsible for making assertions about the state of a page. For example: -``` +```java public void testMessagesAreReadOrUnread() { Inbox inbox = new Inbox(driver); inbox.assertMessageWithSubjectIsUnread("I like cheese"); @@ -398,7 +399,7 @@ public void testMessagesAreReadOrUnread() { could be re-written as: -``` +```java public void testMessagesAreReadOrUnread() { Inbox inbox = new Inbox(driver); assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese")); @@ -421,7 +422,7 @@ Finally, a PageObject need not represent an entire page. It may represent a sect ## Example -``` +```java public class LoginPage { private final WebDriver driver; @@ -490,10 +491,4 @@ public class LoginPage { return submitLogin(); } } - -``` - - -## Support in WebDriver - -There is a PageFactory in the support package that provides support for this pattern and helps to remove some boiler-plate code from your Page Objects at the same time. +``` \ No newline at end of file diff --git a/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.ja.md b/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.ja.md index a269bd4183ce..b89069ddc72d 100644 --- a/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.ja.md +++ b/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.ja.md @@ -199,13 +199,15 @@ requests from the test. ## Page Component Objects A page object does not necessarily need to represent all the parts of a -page itself. The same principles used for page objects can be used to -create "Page _Component_ Objects" that represent discrete chunks of the -page and can be included in page objects. These component objects can +page itself. This was [noted by Martin Fowler](https://martinfowler.com/bliki/PageObject.html#footnote-panel-object) in the early days, while first coining the term "panel objects". + +The same principles used for page objects can be used to +create "Page _Component_ Objects", as it was later called, that represent discrete chunks of the +page and **can be included in page objects**. These component objects can provide references to the elements inside those discrete chunks, and -methods to leverage the functionality provided by them. +methods to leverage the functionality or behavior provided by them. -For example, a Product page has multiple products. +For example, a Products page has multiple products. ```html @@ -243,7 +245,7 @@ Each product is a component of the Products page. ``` -The Product page HAS-A list of products. This relationship is called Composition. In simpler terms, something is _composed of_ another thing. +The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is _composed of_ another thing. ```java public abstract class BasePage { @@ -326,7 +328,7 @@ So now, the products test would use the page object and the page component objec public class ProductsTest { @Test public void testProductInventory() { - var productsPage = new ProductsPage(driver); + var productsPage = new ProductsPage(driver); // page object var products = productsPage.getProducts(); assertEquals(6, products.size()); // expected, actual } @@ -337,7 +339,7 @@ public class ProductsTest { // Pass a lambda expression (predicate) to filter the list of products // The predicate or "strategy" is the behavior passed as parameter - var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); + var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light")); assertEquals(new BigDecimal("29.99"), backpack.getPrice()); @@ -355,8 +357,7 @@ components used throughout the site (e.g. a navigation bar), then it may improve maintainability and reduce code duplication. ## Other Design Patterns Used in Testing -There are other design patterns that also may be used in testing. Some use a -Page Factory for instantiating their page objects. Discussing all of these is +There are other design patterns that also may be used in testing. Discussing all of these is beyond the scope of this user guide. Here, we merely want to introduce the concepts to make the reader aware of some of the things that can be done. As was mentioned earlier, many have blogged on this topic and we encourage the @@ -367,11 +368,11 @@ reader to search for blogs on these topics. PageObjects can be thought of as facing in two directions simultaneously. Facing toward the developer of a test, they represent the **services** offered by a particular page. Facing away from the developer, they should be the only thing that has a deep knowledge of the structure of the HTML of a page (or part of a page) It's simplest to think of the methods on a Page Object as offering the "services" that a page offers rather than exposing the details and mechanics of the page. As an example, think of the inbox of any web-based email system. Amongst the services it offers are the ability to compose a new email, choose to read a single email, and list the subject lines of the emails in the inbox. How these are implemented shouldn't matter to the test. -Because we're encouraging the developer of a test to try and think about the services they're interacting with rather than the implementation, PageObjects should seldom expose the underlying WebDriver instance. To facilitate this, methods on the PageObject should return other PageObjects. This means we can effectively model the user's journey through our application. It also means that should the way that pages relate to one another change (like when the login page asks the user to change their password the first time they log into a service when it previously didn't do that), simply changing the appropriate method's signature will cause the tests to fail to compile. Put another way; we can tell which tests would fail without needing to run them when we change the relationship between pages and reflect this in the PageObjects. +Because we're encouraging the developer of a test to try and think about the services they're interacting with rather than the implementation, PageObjects should seldom expose the underlying WebDriver instance. To facilitate this, **methods on the PageObject should return other PageObjects**. This means we can effectively model the user's journey through our application. It also means that should the way that pages relate to one another change (like when the login page asks the user to change their password the first time they log into a service when it previously didn't do that), simply changing the appropriate method's signature will cause the tests to fail to compile. Put another way; we can tell which tests would fail without needing to run them when we change the relationship between pages and reflect this in the PageObjects. One consequence of this approach is that it may be necessary to model (for example) both a successful and unsuccessful login; or a click could have a different result depending on the app's state. When this happens, it is common to have multiple methods on the PageObject: -``` +```java public class LoginPage { public HomePage loginAs(String username, String password) { // ... clever magic happens here @@ -389,7 +390,7 @@ public class LoginPage { The code presented above shows an important point: the tests, not the PageObjects, should be responsible for making assertions about the state of a page. For example: -``` +```java public void testMessagesAreReadOrUnread() { Inbox inbox = new Inbox(driver); inbox.assertMessageWithSubjectIsUnread("I like cheese"); @@ -399,7 +400,7 @@ public void testMessagesAreReadOrUnread() { could be re-written as: -``` +```java public void testMessagesAreReadOrUnread() { Inbox inbox = new Inbox(driver); assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese")); @@ -422,7 +423,7 @@ Finally, a PageObject need not represent an entire page. It may represent a sect ## Example -``` +```java public class LoginPage { private final WebDriver driver; @@ -491,10 +492,4 @@ public class LoginPage { return submitLogin(); } } - -``` - - -## Support in WebDriver - -There is a PageFactory in the support package that provides support for this pattern and helps to remove some boiler-plate code from your Page Objects at the same time. +``` \ No newline at end of file diff --git a/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.pt-br.md b/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.pt-br.md index ea0efaad9daf..f722fa4b7b49 100644 --- a/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.pt-br.md +++ b/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.pt-br.md @@ -199,13 +199,15 @@ requests from the test. ## Page Component Objects A page object does not necessarily need to represent all the parts of a -page itself. The same principles used for page objects can be used to -create "Page _Component_ Objects" that represent discrete chunks of the -page and can be included in page objects. These component objects can +page itself. This was [noted by Martin Fowler](https://martinfowler.com/bliki/PageObject.html#footnote-panel-object) in the early days, while first coining the term "panel objects". + +The same principles used for page objects can be used to +create "Page _Component_ Objects", as it was later called, that represent discrete chunks of the +page and **can be included in page objects**. These component objects can provide references to the elements inside those discrete chunks, and -methods to leverage the functionality provided by them. +methods to leverage the functionality or behavior provided by them. -For example, a Product page has multiple products. +For example, a Products page has multiple products. ```html @@ -243,7 +245,7 @@ Each product is a component of the Products page. ``` -The Product page HAS-A list of products. This relationship is called Composition. In simpler terms, something is _composed of_ another thing. +The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is _composed of_ another thing. ```java public abstract class BasePage { @@ -326,7 +328,7 @@ So now, the products test would use the page object and the page component objec public class ProductsTest { @Test public void testProductInventory() { - var productsPage = new ProductsPage(driver); + var productsPage = new ProductsPage(driver); // page object var products = productsPage.getProducts(); assertEquals(6, products.size()); // expected, actual } @@ -337,7 +339,7 @@ public class ProductsTest { // Pass a lambda expression (predicate) to filter the list of products // The predicate or "strategy" is the behavior passed as parameter - var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); + var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light")); assertEquals(new BigDecimal("29.99"), backpack.getPrice()); @@ -355,8 +357,7 @@ components used throughout the site (e.g. a navigation bar), then it may improve maintainability and reduce code duplication. ## Other Design Patterns Used in Testing -There are other design patterns that also may be used in testing. Some use a -Page Factory for instantiating their page objects. Discussing all of these is +There are other design patterns that also may be used in testing. Discussing all of these is beyond the scope of this user guide. Here, we merely want to introduce the concepts to make the reader aware of some of the things that can be done. As was mentioned earlier, many have blogged on this topic and we encourage the @@ -367,11 +368,11 @@ reader to search for blogs on these topics. PageObjects can be thought of as facing in two directions simultaneously. Facing toward the developer of a test, they represent the **services** offered by a particular page. Facing away from the developer, they should be the only thing that has a deep knowledge of the structure of the HTML of a page (or part of a page) It's simplest to think of the methods on a Page Object as offering the "services" that a page offers rather than exposing the details and mechanics of the page. As an example, think of the inbox of any web-based email system. Amongst the services it offers are the ability to compose a new email, choose to read a single email, and list the subject lines of the emails in the inbox. How these are implemented shouldn't matter to the test. -Because we're encouraging the developer of a test to try and think about the services they're interacting with rather than the implementation, PageObjects should seldom expose the underlying WebDriver instance. To facilitate this, methods on the PageObject should return other PageObjects. This means we can effectively model the user's journey through our application. It also means that should the way that pages relate to one another change (like when the login page asks the user to change their password the first time they log into a service when it previously didn't do that), simply changing the appropriate method's signature will cause the tests to fail to compile. Put another way; we can tell which tests would fail without needing to run them when we change the relationship between pages and reflect this in the PageObjects. +Because we're encouraging the developer of a test to try and think about the services they're interacting with rather than the implementation, PageObjects should seldom expose the underlying WebDriver instance. To facilitate this, **methods on the PageObject should return other PageObjects**. This means we can effectively model the user's journey through our application. It also means that should the way that pages relate to one another change (like when the login page asks the user to change their password the first time they log into a service when it previously didn't do that), simply changing the appropriate method's signature will cause the tests to fail to compile. Put another way; we can tell which tests would fail without needing to run them when we change the relationship between pages and reflect this in the PageObjects. One consequence of this approach is that it may be necessary to model (for example) both a successful and unsuccessful login; or a click could have a different result depending on the app's state. When this happens, it is common to have multiple methods on the PageObject: -``` +```java public class LoginPage { public HomePage loginAs(String username, String password) { // ... clever magic happens here @@ -389,7 +390,7 @@ public class LoginPage { The code presented above shows an important point: the tests, not the PageObjects, should be responsible for making assertions about the state of a page. For example: -``` +```java public void testMessagesAreReadOrUnread() { Inbox inbox = new Inbox(driver); inbox.assertMessageWithSubjectIsUnread("I like cheese"); @@ -399,7 +400,7 @@ public void testMessagesAreReadOrUnread() { could be re-written as: -``` +```java public void testMessagesAreReadOrUnread() { Inbox inbox = new Inbox(driver); assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese")); @@ -422,7 +423,7 @@ Finally, a PageObject need not represent an entire page. It may represent a sect ## Example -``` +```java public class LoginPage { private final WebDriver driver; @@ -491,10 +492,4 @@ public class LoginPage { return submitLogin(); } } - -``` - - -## Support in WebDriver - -There is a PageFactory in the support package that provides support for this pattern and helps to remove some boiler-plate code from your Page Objects at the same time. +``` \ No newline at end of file diff --git a/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.zh-cn.md b/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.zh-cn.md index d8be43e62da9..ca78de7e2b93 100644 --- a/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.zh-cn.md +++ b/website_and_docs/content/documentation/test_practices/encouraged/page_object_models.zh-cn.md @@ -199,13 +199,15 @@ requests from the test. ## Page Component Objects A page object does not necessarily need to represent all the parts of a -page itself. The same principles used for page objects can be used to -create "Page _Component_ Objects" that represent discrete chunks of the -page and can be included in page objects. These component objects can +page itself. This was [noted by Martin Fowler](https://martinfowler.com/bliki/PageObject.html#footnote-panel-object) in the early days, while first coining the term "panel objects". + +The same principles used for page objects can be used to +create "Page _Component_ Objects", as it was later called, that represent discrete chunks of the +page and **can be included in page objects**. These component objects can provide references to the elements inside those discrete chunks, and -methods to leverage the functionality provided by them. +methods to leverage the functionality or behavior provided by them. -For example, a Product page has multiple products. +For example, a Products page has multiple products. ```html @@ -243,7 +245,7 @@ Each product is a component of the Products page. ``` -The Product page HAS-A list of products. This relationship is called Composition. In simpler terms, something is _composed of_ another thing. +The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is _composed of_ another thing. ```java public abstract class BasePage { @@ -326,7 +328,7 @@ So now, the products test would use the page object and the page component objec public class ProductsTest { @Test public void testProductInventory() { - var productsPage = new ProductsPage(driver); + var productsPage = new ProductsPage(driver); // page object var products = productsPage.getProducts(); assertEquals(6, products.size()); // expected, actual } @@ -337,7 +339,7 @@ public class ProductsTest { // Pass a lambda expression (predicate) to filter the list of products // The predicate or "strategy" is the behavior passed as parameter - var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); + var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light")); assertEquals(new BigDecimal("29.99"), backpack.getPrice()); @@ -355,8 +357,7 @@ components used throughout the site (e.g. a navigation bar), then it may improve maintainability and reduce code duplication. ## Other Design Patterns Used in Testing -There are other design patterns that also may be used in testing. Some use a -Page Factory for instantiating their page objects. Discussing all of these is +There are other design patterns that also may be used in testing. Discussing all of these is beyond the scope of this user guide. Here, we merely want to introduce the concepts to make the reader aware of some of the things that can be done. As was mentioned earlier, many have blogged on this topic and we encourage the @@ -367,11 +368,11 @@ reader to search for blogs on these topics. PageObjects can be thought of as facing in two directions simultaneously. Facing toward the developer of a test, they represent the **services** offered by a particular page. Facing away from the developer, they should be the only thing that has a deep knowledge of the structure of the HTML of a page (or part of a page) It's simplest to think of the methods on a Page Object as offering the "services" that a page offers rather than exposing the details and mechanics of the page. As an example, think of the inbox of any web-based email system. Amongst the services it offers are the ability to compose a new email, choose to read a single email, and list the subject lines of the emails in the inbox. How these are implemented shouldn't matter to the test. -Because we're encouraging the developer of a test to try and think about the services they're interacting with rather than the implementation, PageObjects should seldom expose the underlying WebDriver instance. To facilitate this, methods on the PageObject should return other PageObjects. This means we can effectively model the user's journey through our application. It also means that should the way that pages relate to one another change (like when the login page asks the user to change their password the first time they log into a service when it previously didn't do that), simply changing the appropriate method's signature will cause the tests to fail to compile. Put another way; we can tell which tests would fail without needing to run them when we change the relationship between pages and reflect this in the PageObjects. +Because we're encouraging the developer of a test to try and think about the services they're interacting with rather than the implementation, PageObjects should seldom expose the underlying WebDriver instance. To facilitate this, **methods on the PageObject should return other PageObjects**. This means we can effectively model the user's journey through our application. It also means that should the way that pages relate to one another change (like when the login page asks the user to change their password the first time they log into a service when it previously didn't do that), simply changing the appropriate method's signature will cause the tests to fail to compile. Put another way; we can tell which tests would fail without needing to run them when we change the relationship between pages and reflect this in the PageObjects. One consequence of this approach is that it may be necessary to model (for example) both a successful and unsuccessful login; or a click could have a different result depending on the app's state. When this happens, it is common to have multiple methods on the PageObject: -``` +```java public class LoginPage { public HomePage loginAs(String username, String password) { // ... clever magic happens here @@ -389,7 +390,7 @@ public class LoginPage { The code presented above shows an important point: the tests, not the PageObjects, should be responsible for making assertions about the state of a page. For example: -``` +```java public void testMessagesAreReadOrUnread() { Inbox inbox = new Inbox(driver); inbox.assertMessageWithSubjectIsUnread("I like cheese"); @@ -399,7 +400,7 @@ public void testMessagesAreReadOrUnread() { could be re-written as: -``` +```java public void testMessagesAreReadOrUnread() { Inbox inbox = new Inbox(driver); assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese")); @@ -422,7 +423,7 @@ Finally, a PageObject need not represent an entire page. It may represent a sect ## Example -``` +```java public class LoginPage { private final WebDriver driver; @@ -491,10 +492,4 @@ public class LoginPage { return submitLogin(); } } - -``` - - -## Support in WebDriver - -There is a PageFactory in the support package that provides support for this pattern and helps to remove some boiler-plate code from your Page Objects at the same time. +``` \ No newline at end of file