Skip to content
/ SKDF Public

Yet another implementation of keyword driven framework for Selenium and Protractor

License

Notifications You must be signed in to change notification settings

sergueik/SKDF

Repository files navigation

About SKDF

TestCase.xls

This directory contains a skeleton Keyword-Driven Framework project based on ashokkhape/automation_framework_selenium and ashokkhape/automation_framework_selenium and selenium-webdriver-software-testing/keyword-driven-framework

The project builds two runnable jars (com.github.sergueik.jprotractor and com.github.sergueik.ngwebdriver group id namespaces):

cp TestCase.xls ~/Desktop
pushd jprotractor
mvn  -Pdevelop -DskipTests -Dmaven.test.skip=true install
REM java -jar target/skdf_jprotractor-develop.jar
REM alternatively
java -cp target\skdf_jprotractor-develop.jar;target\lib\* com.github.sergueik.jprotractor.Launcher
popd
pushd ngwebdriver
mvn clean install
REM java -jar target/skdf_ngwebdriver-develop.jar
java -cp target\skdf_ngwebdriver-develop.jar;target\lib\* com.github.sergueik.ngwebdriver.Launcher
popd

The launcher uses reflection to associate keywords with class methods

private static Map<String, String> methodTable = new HashMap<>();
static {
  methodTable.put("CLICK", "clickButton");
  methodTable.put("CLICK_BUTTON", "clickButton");
...
  • a single method may have several keywords pointing to it;
String methodName = methodTable.get(keyword);
try {
  Class<?> _class = Class.forName("com.github.sergueik.ngwebdriver.KeywordLibrary");
  Method _method = _class.getMethod(methodName, Map.class);
  System.out.println(keyword + " call method: " + methodName + " with "
			+ String.join(",", params.values()));
  // for static methods
  _method.invoke(null, params);
  // or when using instances methods
  Object _object = _class.newInstance();
  _method.invoke(_object, params);

Similar approach is used to define Selector strategies, most of which are static methods of the appropriate core Selenium class:

    locatorTable.put("className",
        By.class.getMethod("className", String.class));
    locatorTable.put("css", By.class.getMethod("cssSelector", String.class));
    locatorTable.put("id", By.class.getMethod("id", String.class));
    locatorTable.put("linkText",
        By.class.getMethod("linkText", String.class));
    locatorTable.put("name", By.class.getMethod("name", String.class));
    locatorTable.put("tagName", By.class.getMethod("tagName", String.class));
    locatorTable.put("xpath", By.class.getMethod("xpath", String.class));

with few "synthetic" strategies, notably the TEXT:

// put synthetic selectors explicitly
  locatorTable.put("text", methodMissing);

implemented e.g. through xpath:

  String amendedSelectorValue = String.format(
      "//%s[contains(normalize-space(text()),'%s')]",
      (selectorTagName != null) ? selectorTagName : "*", selectorValue);
  _element = _wait.until(new ExpectedCondition<WebElement>() {
    @Override
    public WebElement apply(WebDriver d) {
      return d.findElements(By.xpath(amendedSelectorValue)).stream()
          .filter(o -> {
            return (Boolean) (o.getText().contains(selectorValue));
          }).findFirst().get();
    }
  });

The test step arguments are passed as hash of parameters. That is done so one does not care about the method signature. Also the AngularJS introduced NgBy locators which fequently require (multiple) additional arguments like e.g.

@FindBy(how = How.REPEATER_COLUMN, using = "row in rows", column = "name")
private List<WebElement> friendNames;

The step status is returned via params["status"] entry, the step result (if any) is returned via params["result"]

Adding Tests to the Spreadsheet

To add a test case, put its name into the Index sheet and mark it with Yes to be executed index

Next, add the steps. Making the cell border visible will ensure the blank cells are not getting skipped: demoqa

Adding jProtractor

One can explore additional selectors with jProtractor.

TestCase.xls

jProtractor is not available in maven central, therefore to use it with framework one needs do build it from source and install it into current user's .m2 repo:

git clone https://github.com/sergueik/jProtractor.git
pushd jProtractor
mvn -Dmaven.test.skip=true clean install

which will install the jar:

[INFO] Installing C:\developer\sergueik\selenium_java\protractor\target\jprotractor-1.2-SNAPSHOT.jar to C:\Users\Serguei\.m2\repository\com\jprotractor\jprotractor\1.2-SNAPSHOT\jprotractor-1.2-SNAPSHOT.jar
[INFO] Installing C:\developer\sergueik\selenium_java\protractor\pom.xml to C:\Users\Serguei\.m2\repository\com\jprotractor\jprotractor\1.2-SNAPSHOT\jprotractor-1.2-SNAPSHOT.pom

This will add about 10 AngularJS-specific NgBy locators:

NgBy methods

  • options
  • input
  • selectedOption
  • repeater
  • model
  • binding
  • repeaterElement
  • repeaterRows
  • buttonText
  • repeaterColumn
  • cssContainingText
  • selectedRepeaterOption
  • partialButtonText

Adding ngWebDriver

Another implementation of Protractor selectors is ngWebDriver.

ByAngular methods

Most Protractor-specific locators are the same (the class is ByAngular):

  • options
  • repeater
  • model
  • binding
  • buttonText
  • cssContainingText
  • partialButtonText

Few method signatures of are different:

  • repeaterCell
  • repeaterRow
  • repeaterColumn

The implementation of the correspondent keyword methods is through chaining the ngWebDriver methods e.g.

case "repeaterColumn":
  ngDriver.waitForAngularRequestsToFinish();
  ByAngularRepeater _elementRepeater = ByAngular.repeater(selectorValue);
  ByAngularRepeaterColumn _elementRepeaterColumn = _elementRepeater.column(selectorColumn);
  _element = driver.findElement(_elementRepeaterColumn);
  return _element;

Some methods are unique to jProtracror, they do not exist in ngWebDriver:

  • selectedOption
  • selectedRepeaterOption

In addition the "text" keyword is recognized with the usual implementation through xpath locator:

String.format("//%s[contains(normalize-space(text()), '%s')]", (selectorTagName != null) ? selectorTagName : "*", selectorValue);

alternatively if the selectorTagName is provided, the Java 8 stream based impplementation is possible:

_element = driver.findElements(By.tagName(selectorTagName)).stream()
  .filter(o -> o.getText().contains(selectorValue)).findFirst().get();

Introduction

The original Keyword Driven Framework suggests identifying few columns (not necessarily exactly four, though).

  • Summary: brief description of the step
  • Target: name of the Web Page object/element, like "Link" or "Input"
  • Action: name of the action, which will be performed on Target Element such as click, open browser, input text etc.
  • Data: any value which is needed by the Object to perform any action, like text value for input field.

It is very likely inspired by selenium_ide

Selenium IDE Firefox Add-On Command, Target, Value columns, with significanylty narrowed choice of commands (Keywords). The advantages from taking such approach are discussed many times:

  • Less Technical Expertise:  manual testers or non technical testers can easily write test scripts for automation using the Framework than code straight.
  • Easy To Understand: With no coding is exposed, the test flow is easy to read and understand. Keywords & actions are descriptive.
  • Early Start: One can start building Keyword Driven test cases immediately deferring more challenging tasks like Page Object model to a later stage. Keyword steps are quick to identify from requirements documentation or manual test.
  • Re-usability: With implementing modularization in Keyword Driven, Re-usability can be further increased. Equipped with a stable and powerful Execution Engine in Keyword Driven Framework, it encourage extreme code re-usability.
  • Automation: Excel file is (a lot) easier to produce by a recording tool than a full blown program.

Work in Progress

Adding

No keywords defined for any of those yet.

Note

the urls http://www.seleniumeasy.com/test/basic-first-form-demo.html and https://www.seleniumeasy.com/test/input-form-demo.html no longer exist on http://www.seleniumeasy.com though the former is still referenced in documentation for Python testers.

These pages were apparently mirrored on https://demo.anhtester.com The directory http://www.seleniumeasy.com/test/ is also gone and there is no mirror The update of test material is a work in progress. The sheets KeywordFramework are curently disabled. The Alert sheet is updated and enabled (it had a typo in the custom method name for processing the alert popup)

See Also

License

This project is licensed under the terms of the MIT license.

Author

Serguei Kouzmine

About

Yet another implementation of keyword driven framework for Selenium and Protractor

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published