
package com.smartgwt.client.docs;

/**
 * <h3>Automated Testing</h3>
 * Smart GWT supports automated testing with a variety of tools. See the {@link
 * com.smartgwt.client.util.AutoTest} class
 * for information about how to generate and resolve {@link
 * com.smartgwt.client.docs.AutoTestLocator AutoTestLocators}
 *  and other utilities within the Smart GWT framework related to generating automated tests.
 *  <P>
 *  <h3>Playwright</h3>
 * Smart GWT applications work smoothly with <a href='https://playwright.dev/'
 * target='_blank'>Playwright</a>.
 *  <P>
 *  The SDK package provides an example <code>commands.js</code> file that defines 
 * <a href='https://playwright.dev/docs/test-fixtures' target='_blank'>Playwright fixtures and
 * helpers</a> 
 *  designed to locate and interact with Smart GWT components, automatically handle 
 *  asynchronous operations, record performance data, and more. 
 *  For step-by-step guidance on using Playwright with Smart GWT, 
 * see {@link com.smartgwt.client.docs.SmartClientPlaywright Integrating Smart GWT with
 * Playwright}.
 *  <P>
 *  <h3>Cypress</h3>
 * Smart GWT applications integrate seamlessly with <a href='https://www.cypress.io/'
 * target='_blank'>Cypress</a>.
 *  <P>
 *  The SDK package includes a sample <code>commands.js</code> configuration file with custom 
 * <a href='https://docs.cypress.io/api/cypress-api/custom-commands' target='_blank'>cypress
 * commands</a> to
 *  identify and interact with Smart GWT components, seamlessly wait for asynchronous 
 *  operations, recording timing data and more. See the
 * {@link com.smartgwt.client.docs.SmartClientCypress Cypress integration overview} for details on
 * how to
 *  use Cypress with Smart GWT.
 *  <P>
 *  <h3>Selenese</h3>
 *  <P>
 *  Selenese is a simple HTML table-based test format that can be authored without programming
 *  skills.  Smart GWT provides enhanced Selenese commands and locators for reliable
 *  interaction with Smart GWT widgets.
 *  <P>
 *  
 *  <b>Java-based SeleneseRunner</b>
 *  <P>
 *  For Java-based environments, Smart GWT provides
 * <a href='../../../../../server/javadoc/com/isomorphic/webdriver/SeleneseRunner.html'
 * target='_blank'>SeleneseRunner</a>, which
 *  executes Selenese via WebDriver.  This runner can also convert Selenese to Java/JUnit code.
 *  <P>
 *  <b>Recording Selenese</b>
 *  <P>
 * Selenese tests can be recorded using Selenium IDE.  See {@link
 * com.smartgwt.client.docs.UsingSelenium Using\n Selenium} for setup instructions.  Note that
 * while Selenium IDE 2.9 (with Firefox 52 ESR)
 *  provides the best recording experience with Smart GWT extensions, recorded tests can be
 *  executed via the Playwright runner without any Selenium installation.
 *  <P>
 *  <h3>TestRunner</h3>
 *  <P>
 * {@link com.smartgwt.client.docs.TestRunner TestRunner} is a system for automatically running a
 * suite of Selenium
 * tests, commiting the results to a database, and reporting any regressions (or fixes) via email.
 *  <P>
 *  
 *  <h3>GwtTestCase</h3>
 *  <P>
 *  GWT includes a way to run a GWT application under JUnit, running your GWT application in a
 *  "headless" browser.  This is a very limited testing approach appropriate for certain unit
 *  tests only - it cannot replace events such as clicks, because by default it doesn't run in
 *  actual browser (instead it runs in a simulator called HtmlUnit).
 *  <p>
 *  Note that running tests under HtmlUnit can lead to false failures in a variety of areas,
 *  including network communication and XML processing, where HtmlUnit's behaviors do not
 *  correspond to any real browser.  Note that, if you find that a test fails under HtmlUnit but
 *  would not fail in a real browser, this will not be regarded as a SmartGWT bug.
 *  <p>
 *  If you use GwtTestCase at all, Isomorphic recommends that the majority of your tests are
 *  executed using the
 * <a href='http://www.gwtproject.org/doc/latest/DevGuideTestingRemoteTesting.html'
 * target='_blank'>runStyle option</a>
 *  that allows GwtTestCase to run under a real browser via Selenium.
 *  <P>
 *  Also note, GwtTestCase has a bug where it does not run onModuleLoad() for included GWT
 *  modules.  To make sure SmartGWT's onModuleLoad() runs, add a <code>gwtSetUp()</code>
 *  implementation like so: 
 *  <P>
 *  <pre>
 *    public class SgwtTest extends GWTTestCase {
 *        public void gwtSetUp() {
 *            new SmartGwtEntryPoint().onModuleLoad();  
 *        }
 *        ...
 *  </pre>
 *  <P>
 *  You may need to add similar manual calls for other GWT modules you inherit which expect to
 *  have their <code>onModuleLoad()</code> method called normally.
 *  
 *  <P>
 *  <h3>Selenium WebDriver</h3>
 *  <P>
 *  WebDriver uses browser-specific drivers to enable Selenium interaction.  Smart GWT provides
 *  WebDriver support with the same custom locator strategies and commands as Selenese.
 *  <P>
 *  For most use cases, we recommend Playwright or Cypress over WebDriver, as they provide
 *  a more modern development experience.  WebDriver remains useful for teams with existing
 *  Java/Selenium infrastructure or specific integration requirements.
 *  <P>
 *  <b>WebDriver Usage</b>
 *  <P>
 *  You can use Selenium IDE to record tests, then use <code>SeleneseRunner</code> to convert
 *  the Selenese to Java code that uses Smart GWT locators and our WebDriver wrappers.
 *  <P>
 * To retrieve locators for hand-written tests, use {@link
 * com.smartgwt.client.util.AutoTest#installLocatorShortcut AutoTest.installLocatorShortcut()}
 * (key-combo plus click) or {@link com.smartgwt.client.util.AutoTest#getLocator
 * AutoTest.getLocator()} from the
 *  {@link com.smartgwt.client.docs.Debugging Developer Console}.
 *  <p>
 *  <b>NOTE:</b> Do not use Selenium IDE's built-in WebDriver export feature; it doesn't
 *  support custom commands or locators.  Use <code>SeleneseRunner</code> instead.
 *  <p>
 *  <b>WebDriver Classes overview</b>
 *  <p>
 *  For certain tests it can make sense to use WebDriver Java support directly.
 *  <p>
 *  Smart GWT support for WebDriver is based around 3 different Java classes:
 *  <P>
 *  <ol>
 * <li> <a href='../../../../../server/javadoc/com/isomorphic/webdriver/ByScLocator.html'
 * target='_blank'>ByScLocator</a>:
 *  This implements the ability to find WebElements or WebDriver "By"
 * objects using Smart GWT Locator strings.  See {@link com.smartgwt.client.docs.UsingSelenium}
 * for more
 * background on Locator strings and how to obtain them.  Given a locator String, example usage
 * is:
 *  <pre>
 *  ByScLocator.scLocator("//ListGrid[ID=\"countryList\"]/body/row[countryCode=US||0]/col[fieldName=countryCode||0]")</pre>
 * <li> <a href='../../../../../server/javadoc/com/isomorphic/webdriver/SmartClientWebDriver.html'
 * target='_blank'>SmartClientWebDriver</a>:
 *  This is an abstract class which provides a number of
 *  different methods for interacting with the browser, such as:
 *  <ul>
 *  <li> open a browser at a particular URL
 *  <li> find the element or elements which match a given "By" object (either ByScLocator, or a
 *       standard WebDriver locator)
 *  <li> perform events and operations (click, drag, select etc)
 *  <li> perform custom Smart GWT validations / state checks, such as whether a grid has
 *       loaded data
 *  </ul>
 *  Three concrete implementations of SmartClientWebDriver are provided: SmartClientFireFoxDriver,
 * SmartClientChromeDriver and SmartClientIEDriver. There is also a SmartClientRemoteWebdriver
 * class
 *  which allows the injection of a manually configured RemoteWebDriver instance. This might be
 *  necessary, for example, for use with Selenium Grid.<P>
 * <li> <a href='../../../../../server/javadoc/com/isomorphic/webdriver/ScActions.html'
 * target='_blank'>ScActions</a>:
 *  a Smart GWT-specific version of the standard WebDriver
 *  "Action" class, providing a builder pattern to create a sequence of operations which can
 *  then be perform()ed.
 *  </ol>
 *  <P>
 *  These classes are packaged in the library isomorphic_webdriver.jar, which can be found in
 *  the directory lib-WebDriverSupport (along with several
 *  3rd-party supporting libraries).This directory can be found at the top level of the
 *  downloaded Smart GWT zip package.
 *  <P>
 *  General information regarding WebDriver can be found
 * <a href='http://docs.seleniumhq.org/docs/03_webdriver.jsp#introducing-webdriver'
 * target='_blank'>here</a>.
 *  Setup for WebDriver is more complex than for classic Selenium.  Drivers can be downloaded for
 *  <a href='https://github.com/mozilla/geckodriver/' target='_blank'>Firefox</a>,
 *  <a href='https://sites.google.com/chromium.org/driver/' target='_blank'>Google Chrome</a>, 
 *  <a href='https://www.seleniumhq.org/download/' target='_blank'>Internet Explorer</a>, and
 * <a href='https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/'
 * target='_blank'>MS Edge</a>.
 *  <P>
 *  <b>JUnit + WebDriver</b>
 *  <P>
 * Explore {@link com.smartgwt.client.docs.JUnitWebDriver JUnit + Selenium WebDriver}, where we
 * walk through a JUnit test
 *  targeting a Smart GWT Showcase sample.
 *  <P>
 *  <b>File Upload Example Test</b>
 *  <P>
 * As discussed above, one advantage which WebDriver does have over Classic Selenium is the
 * ability
 * to test file upload. It is still limited in that if a click is triggered on the file selection
 * button
 * an OS native file selection dialog will be triggered in which case the test will be suspended
 * until the
 * file is manually selected. To avoid this, the sendKeys() method can be used to enter the file
 * location.
 *  <p>Sample code:<p>
 *  <pre>
 *     &#47;**
 *      * The following test runs against localhost and requires a small (< 5mb) image to be in /tmp/image.jpg
 *      *&#47;
 *     public void fileUploadGWT() throws Exception {
 *         final String basePath = "//VLayout[ID=\"isc_Showcase_1_0\"]/member[Class=HLayout||index=0||length=2|"
 *                                +"|classIndex=0||classLength=1]/member[Class=HLayout||index=0||length=2||classIndex=0|"
 *                                +"|classLength=1]/member[Class=Canvas||index=1||length=2||classIndex=0||classLength=1]"
 *                                +"/child[Class=TabSet||index=0||length=1||classIndex=0||classLength=1]/paneContainer/"
 *                                +"member[Class=VLayout||index=1||length=2||classIndex=0||classLength=1]/"
 *                                +"member[Class=VLayout||index=1||length=2||classIndex=0||classLength=1]/"
 *                                +"member[Class=HLayout||index=1||length=2||classIndex=0||classLength=1]/"
 *                                +"member[Class=HLayout||index=0||length=1||classIndex=0||classLength=1]/";
 *         final String formPath = basePath + "member[Class=DynamicForm||index=0||length=3||classIndex=0||classLength=1]";
 *         final String tilesPath = basePath + "member[Class=VLayout||index=2||length=3||classIndex=0||classLength=1]/"
 *                                           + "member[Class=TileGrid||index=2||length=4||classIndex=0||classLength=1]/tile";
 *         SmartClientWebDriver driver = new SmartClientFirefoxDriver();
 *         driver.setBaseUrl("http://localhost:8888/");
 *         driver.get("index.html#upload_sql", true);
 * 
 *         final int origSize = driver.findElements(ByScLocator.scLocator(tilesPath)).size();
 *         By uploadForm = ByScLocator.scLocator(formPath);
 *         WebElement form = driver.findElement(uploadForm);
 *       
 *         By titleInput = ByScLocator.scLocator(formPath + "/item[name=title||title=Title||index=0||Class=TextItem]/element");
 *         driver.click(titleInput);
 *         driver.sendKeys(titleInput, "test image: " + origSize);
 *         
 *         WebElement findElement = form.findElement(By.xpath("//input[@type='FILE']"));
 *         &#47;*
 *          * The following causes a native dialog to be created which prevents further progress. Do NOT uncomment!
 *          * We just have to sendKeys() to it
 *          *&#47;
 *         //findElement.click(); 
 *         
 *         findElement.sendKeys("/tmp/image.jpg"); // A local file. Please change accordingly
 * 
 *         By saveButton = ByScLocator.scLocator(formPath + "/item[title=Save||index=2||Class=ButtonItem]/button/");
 *         driver.waitForElementClickable(saveButton);
 *         driver.click(saveButton);
 *         &#47;*
 *          * Note the following fails once the grid contains more than 3 rows of data as the index becomes inconsistent
 *          * as tiles scrolled out of site are removed and the indices change
 *          *&#47;
 *         By tile = ByScLocator.scLocator(tilesPath + "[Class=SimpleTile||index="+(origSize)+"||length="+(origSize+1)
 *                                                       + "||classIndex="+(origSize)+"||classLength="+(origSize+1)+"]/");
 *         driver.waitForElementClickable(tile);
 *         WebElement tile1 = driver.findElement(tile);
 *         assertEquals("test image: " + origSize, tile1.getText());
 *         assertEquals(origSize + 1, driver.findElements(ByScLocator.scLocator(tilesPath)).size());
 *         driver.close();
 *         driver.quit();
 *     }
 *  </pre>
 *  <P>
 *  <b>WebDriver Troubleshooting</b>
 *  <P>
 *  There is a known issue that 
 * <a href='https://code.google.com/p/selenium/issues/detail?id=4403' target='_blank'>native
 * events do not work with IE in Windows 8/8.1</a>
 *  that may manifest in WebDriver as clicks having no effect.  One potential workaround is to
 *  disable native events:
 *  <pre>
 *     DesiredCapabilities caps = DesiredCapabilities.internetExplorer();
 *     caps.setCapability("nativeEvents",false);
 *     SmartClientWebDriver driver = new SmartClientIEDriver(caps);</pre>
 *  It's also been reported that changing the second line above to:
 *  <pre>
 *     caps.setCapability("requireWindowFocus", true);</pre>
 *  also resolves the issue, with the side effect that WebDriver then moves the mouse cursor.
 *  <P>
 *  In some versions of Internet Explorer, it's been reported that you must add the URL targeted
 *  by WebDriver to the "Trusted Sites" under Internet Options &gt;&gt; Security in order to
 *  allow the browser to communicate properly with Selenium.  A discussion of the setup needed
 *  to use WebDriver's InternetExplorerDriver can be found
 * <a href='https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver'
 * target='_blank'>here</a>.
 *  <P>
 *  <b>Other tools</b>
 *  <P>
 *  Smart GWT supports a special JavaScript API to allow other test tools to integrate in the
 *  same manner as Selenium and WebDriver.  This API allows the test tool to record an abstract
 *  "locator" string representing the logical name for an interactive DOM element, and then
 *  during test playback, retrieve a DOM element given a locator.
 *  <P>
 *  This is critical because, like many modern Ajax systems, Smart GWT generates different DOM
 *  elements in different browsers, in different skins, and in different versions of Smart GWT.  
 *  Testing tools that try to directly record the generated Smart GWT DOM produce extremely
 *  brittle tests because they are effectively recording undocumented internals.
 *  <P>
 *  Using the "locator" API allows you to record or write tests that will run in any browser
 *  supported by Smart GWT, in any version of Smart GWT, and in any skin.  It also makes
 *  tests more readable and easier to understand and maintain.
 *  <P>
 *  Different testing tools vary in how easily they can be configured to use the locator API,
 *  and in some older tools it can be a large effort.  We highly recommend using our Selenium
 *  extensions - it often makes sense to use them even if you have to use them in parallel with
 *  another, older testing tool.  If you are forced to use another tool exclusively:
 *  <ul>
 *  
 *  
 *  <li> Refer to the &#83;martClient documentation for the AutoTest class (because it's a
 *  JavaScript API).  It can be found
 *  <a href='http://www.smartclient.com/product/documentation.jsp' target='_blank'>here</a>
 *  
 *  <li> Read over the source code of our Selenium extensions to get a clear understanding of
 *  how the Selenium integration works, because this will be analogous to the work you'll need
 *  to do
 * <li> Search the <a href='http://forums.smartclient.com/' target='_blank'>forums</a> for other
 * developers
 *  who are trying to use the same test tool with Smart GWT, and share efforts
 *  </ul>
 * @see com.smartgwt.client.tools.stream.EventStream#getAsSeleneseHTML
 * @see com.smartgwt.client.tools.stream.EventStream#getAsSeleneseCommands
 */
public interface AutomatedTesting {
}
