Robot framework (#1304)
* added Robot framework UI tests * added Robot framework UI tests workflow * Update test.yml wait in workflow * remove obsolete selenium java libs and test * Update test.yml push result to commit as comment * Update test.yml push comment does not seem to work on WebGoat PR * clean up unrequired robot options * update readme
This commit is contained in:
		
							
								
								
									
										66
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,66 @@ | |||||||
|  | name: "UI-Test" | ||||||
|  | on: | ||||||
|  |     pull_request: | ||||||
|  |         paths-ignore: | ||||||
|  |             - '.txt' | ||||||
|  |             - '*.MD' | ||||||
|  |             - '*.md' | ||||||
|  |             - 'LICENSE' | ||||||
|  |             - 'docs/**' | ||||||
|  |     push: | ||||||
|  |         tags-ignore: | ||||||
|  |             - '*' | ||||||
|  |         paths-ignore: | ||||||
|  |             - '.txt' | ||||||
|  |             - '*.MD' | ||||||
|  |             - '*.md' | ||||||
|  |             - 'LICENSE' | ||||||
|  |             - 'docs/**' | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |     build: | ||||||
|  |         runs-on: ubuntu-latest | ||||||
|  |         # display name of the job | ||||||
|  |         name: "Robot framework test" | ||||||
|  |         steps: | ||||||
|  |             # Uses an default action to checkout the code | ||||||
|  |             - uses: actions/checkout@v3 | ||||||
|  |             # Uses an action to add Python to the VM | ||||||
|  |             - name: Setup Pyton | ||||||
|  |               uses: actions/setup-python@v4 | ||||||
|  |               with: | ||||||
|  |                   python-version: '3.7' | ||||||
|  |                   architecture: x64 | ||||||
|  |             # Uses an action to add JDK 17 to the VM (and mvn?) | ||||||
|  |             - name: set up JDK 17 | ||||||
|  |               uses: actions/setup-java@v3 | ||||||
|  |               with: | ||||||
|  |                   distribution: 'temurin' | ||||||
|  |                   java-version: 17 | ||||||
|  |                   architecture: x64 | ||||||
|  |             #Uses an action to set up a cache using a certain key based on the hash of the dependencies | ||||||
|  |             - name: Cache Maven packages | ||||||
|  |               uses: actions/cache@v3.0.5 | ||||||
|  |               with: | ||||||
|  |                   path: ~/.m2 | ||||||
|  |                   key: ubuntu-latest-m2-${{ hashFiles('**/pom.xml') }} | ||||||
|  |                   restore-keys: ubuntu-latest-m2- | ||||||
|  |             - uses: BSFishy/pip-action@v1 | ||||||
|  |               with: | ||||||
|  |                   packages: | | ||||||
|  |                       robotframework | ||||||
|  |                       robotframework-SeleniumLibrary | ||||||
|  |                       webdriver-manager | ||||||
|  |             - name: Run with Maven | ||||||
|  |               run: mvn --no-transfer-progress spring-boot:run & | ||||||
|  |             - name: Wait to start | ||||||
|  |               uses: ifaxity/wait-on-action@v1 | ||||||
|  |               with: | ||||||
|  |                   resource: http://127.0.0.1:8080/WebGoat | ||||||
|  |             - name: Test with Robotframework | ||||||
|  |               run: python3 -m robot --variable HEADLESS:"1" --outputdir robotreport robot/goat.robot | ||||||
|  |             #- name: Send report to commit | ||||||
|  |            #   uses: joonvena/robotframework-reporter-action@v2.1 | ||||||
|  |             #  with: | ||||||
|  |        #           gh_access_token: ${{ secrets.GITHUB_TOKEN }} | ||||||
|  |           #        report_path: 'robotreport' | ||||||
							
								
								
									
										10
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								pom.xml
									
									
									
									
									
								
							| @ -514,21 +514,11 @@ | |||||||
|             <artifactId>wiremock</artifactId> |             <artifactId>wiremock</artifactId> | ||||||
|             <scope>test</scope> |             <scope>test</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|         <dependency> |  | ||||||
|             <groupId>org.seleniumhq.selenium</groupId> |  | ||||||
|             <artifactId>selenium-java</artifactId> |  | ||||||
|             <scope>test</scope> |  | ||||||
|         </dependency> |  | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>io.rest-assured</groupId> |             <groupId>io.rest-assured</groupId> | ||||||
|             <artifactId>rest-assured</artifactId> |             <artifactId>rest-assured</artifactId> | ||||||
|             <scope>test</scope> |             <scope>test</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|         <dependency> |  | ||||||
|             <groupId>io.github.bonigarcia</groupId> |  | ||||||
|             <artifactId>webdrivermanager</artifactId> |  | ||||||
|             <scope>test</scope> |  | ||||||
|         </dependency> |  | ||||||
|     </dependencies> |     </dependencies> | ||||||
|  |  | ||||||
|     <build> |     <build> | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								robot/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								robot/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | # Install and use Robotframework | ||||||
|  |  | ||||||
|  | ## Install Chromedriver on Mac OS | ||||||
|  |  | ||||||
|  |     brew install cask chromedriver | ||||||
|  |     chromedriver --version | ||||||
|  |  | ||||||
|  | Then see security settings and allow the file to run | ||||||
|  |  | ||||||
|  | ## Install | ||||||
|  |  | ||||||
|  |     pip3 install virtualenv --user | ||||||
|  |     python3 -m virtualenv .venv | ||||||
|  |     source .venv/bin/activate | ||||||
|  |     pip install robotframework | ||||||
|  |     pip install robotframework-SeleniumLibrary | ||||||
|  |     pip install webdriver-manager | ||||||
|  |     robot --variable HEADLESS:"0" --variable ENDPOINT:"http://127.0.0.1:8080/WebGoat" goat.robot | ||||||
							
								
								
									
										101
									
								
								robot/goat.robot
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								robot/goat.robot
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,101 @@ | |||||||
|  | *** Settings *** | ||||||
|  | Documentation  Setup WebGoat Robotframework tests | ||||||
|  | Library  SeleniumLibrary  timeout=100  run_on_failure=Capture Page Screenshot | ||||||
|  | Library  String | ||||||
|  |  | ||||||
|  | Suite Setup  Initial_Page  ${ENDPOINT}  ${BROWSER} | ||||||
|  | Suite Teardown  Close_Page | ||||||
|  |  | ||||||
|  | *** Variables *** | ||||||
|  | ${BROWSER}  chrome | ||||||
|  | ${SLEEP}  100 | ||||||
|  | ${DELAY}  0.25 | ||||||
|  | ${ENDPOINT}  http://127.0.0.1:8080/WebGoat | ||||||
|  | ${ENDPOINT_WOLF}  http://127.0.0.1:9090 | ||||||
|  | ${USERNAME}  robotuser | ||||||
|  | ${PASSWORD}  password | ||||||
|  | ${HEADLESS}  ${FALSE} | ||||||
|  |  | ||||||
|  | *** Keywords *** | ||||||
|  | Initial_Page | ||||||
|  |   [Documentation]  Check the inital page | ||||||
|  |   [Arguments]  ${ENDPOINT}  ${BROWSER} | ||||||
|  |   Log To Console  Start WebGoat UI Testing | ||||||
|  |   IF  ${HEADLESS} | ||||||
|  |       Open Browser  ${ENDPOINT}  ${BROWSER}  options=add_argument("-headless");add_argument("--start-maximized");add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'})  alias=webgoat | ||||||
|  |   ELSE | ||||||
|  |       Open Browser  ${ENDPOINT}  ${BROWSER}  options=add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'})  alias=webgoat | ||||||
|  |   END | ||||||
|  |   IF  ${HEADLESS} | ||||||
|  |       Open Browser  ${ENDPOINT_WOLF}/WebWolf  ${BROWSER}  options=add_argument("-headless");add_argument("--start-maximized");add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'})  alias=webwolf | ||||||
|  |   ELSE | ||||||
|  |       Open Browser  ${ENDPOINT_WOLF}/WebWolf  ${BROWSER}  options=add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'})  alias=webwolf | ||||||
|  |   END | ||||||
|  |   Switch Browser  webgoat | ||||||
|  |   Maximize Browser Window | ||||||
|  |   Set Window Size  ${1400}  ${1000} | ||||||
|  |   Switch Browser  webwolf | ||||||
|  |   Maximize Browser Window | ||||||
|  |   Set Window Size  ${1400}  ${1000} | ||||||
|  |   Set Window Position  ${400}  ${200} | ||||||
|  |   Set Selenium Speed  ${DELAY} | ||||||
|  |  | ||||||
|  | Close_Page | ||||||
|  |   [Documentation]  Closing the browser | ||||||
|  |   Log To Console  ==> Stop WebGoat UI Testing | ||||||
|  |   IF  ${HEADLESS} | ||||||
|  |     Switch Browser  webgoat | ||||||
|  |     Close Browser | ||||||
|  |     Switch Browser  webwolf | ||||||
|  |     Close Browser | ||||||
|  |   END | ||||||
|  |  | ||||||
|  | *** Test Cases *** | ||||||
|  |  | ||||||
|  | Check_Initial_Page | ||||||
|  |   Switch Browser  webgoat | ||||||
|  |   Page Should Contain  Username | ||||||
|  |   Click Button  Sign in | ||||||
|  |   Page Should Contain  Invalid username | ||||||
|  |   Click Link  /WebGoat/registration | ||||||
|  |  | ||||||
|  | Check_Registration_Page | ||||||
|  |   Page Should Contain  Username | ||||||
|  |   Input Text  username  ${USERNAME} | ||||||
|  |   Input Text  password  ${PASSWORD} | ||||||
|  |   Input Text  matchingPassword  ${PASSWORD} | ||||||
|  |   Click Element  agree | ||||||
|  |   Click Button  Sign up | ||||||
|  |  | ||||||
|  | Check_Welcome_Page | ||||||
|  |   Page Should Contain  WebGoat | ||||||
|  |   Go To  ${ENDPOINT}/login | ||||||
|  |   Page Should Contain  Username | ||||||
|  |   Input Text  username  ${USERNAME} | ||||||
|  |   Input Text  password  ${PASSWORD} | ||||||
|  |   Click Button  Sign in | ||||||
|  |   Page Should Contain  WebGoat | ||||||
|  |  | ||||||
|  | Check_Menu_Page | ||||||
|  |   Click Element  css=a[category='Introduction'] | ||||||
|  |   Click Element  Introduction-WebGoat | ||||||
|  |   CLick Element  Introduction-WebWolf | ||||||
|  |   Click Element  css=a[category='General'] | ||||||
|  |   CLick Element  General-HTTPBasics | ||||||
|  |   Click Element  xpath=//*[.='2'] | ||||||
|  |   Input Text     person  ${USERNAME} | ||||||
|  |   Click Button   Go! | ||||||
|  |   ${OUT_VALUE}   Get Text  xpath=//div[contains(@class, 'attack-feedback')] | ||||||
|  |   ${OUT_RESULT}  Evaluate  "resutobor" in """${OUT_VALUE}""" | ||||||
|  |   IF  not ${OUT_RESULT} | ||||||
|  |     Fail  "not ok" | ||||||
|  |   END | ||||||
|  |  | ||||||
|  | Check_WebWolf | ||||||
|  |   Switch Browser  webwolf | ||||||
|  |   location should be  ${ENDPOINT_WOLF}/WebWolf | ||||||
|  |   Go To  ${ENDPOINT_WOLF}/mail | ||||||
|  |   Input Text  username  ${USERNAME} | ||||||
|  |   Input Text  password  ${PASSWORD} | ||||||
|  |   Click Button  Sign In | ||||||
|  |  | ||||||
| @ -1,111 +0,0 @@ | |||||||
| package org.owasp.webgoat; |  | ||||||
|  |  | ||||||
| import java.util.concurrent.TimeUnit; |  | ||||||
|  |  | ||||||
| import org.junit.jupiter.api.AfterEach; |  | ||||||
| import org.junit.jupiter.api.BeforeEach; |  | ||||||
| import org.junit.jupiter.api.Test; |  | ||||||
| import org.openqa.selenium.By; |  | ||||||
| import org.openqa.selenium.WebDriver; |  | ||||||
| import org.openqa.selenium.firefox.FirefoxBinary; |  | ||||||
| import org.openqa.selenium.firefox.FirefoxDriver; |  | ||||||
| import org.openqa.selenium.firefox.FirefoxOptions; |  | ||||||
|  |  | ||||||
| import io.github.bonigarcia.wdm.WebDriverManager; |  | ||||||
| import io.github.bonigarcia.wdm.config.DriverManagerType; |  | ||||||
|  |  | ||||||
| public class SeleniumIntegrationTest extends IntegrationTest { |  | ||||||
|  |  | ||||||
| 	static { |  | ||||||
| 		try { |  | ||||||
| 			WebDriverManager.getInstance(DriverManagerType.FIREFOX).setup(); |  | ||||||
| 		} catch (Exception e) { |  | ||||||
| 			//sometimes a 403 cause an ExceptionInInitializerError |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	private WebDriver driver; |  | ||||||
|  |  | ||||||
| 	@BeforeEach |  | ||||||
| 	public void setUpAndLogin() { |  | ||||||
| 		try { |  | ||||||
| 			FirefoxBinary firefoxBinary = new FirefoxBinary(); |  | ||||||
| 			firefoxBinary.addCommandLineOptions("--headless"); |  | ||||||
|  |  | ||||||
| 			FirefoxOptions firefoxOptions = new FirefoxOptions(); |  | ||||||
| 			firefoxOptions.setBinary(firefoxBinary); |  | ||||||
| 			driver = new FirefoxDriver(firefoxOptions); |  | ||||||
| 			driver.get(url("/login")); |  | ||||||
| 			driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); |  | ||||||
| 			// Login |  | ||||||
| 			driver.findElement(By.name("username")).sendKeys(this.getUser()); |  | ||||||
| 			driver.findElement(By.name("password")).sendKeys("password"); |  | ||||||
| 			driver.findElement(By.className("btn")).click(); |  | ||||||
|  |  | ||||||
| 			// Check if user exists. If not, create user. |  | ||||||
| 			if (driver.getCurrentUrl().equals(url("/login?error"))) { |  | ||||||
| 				driver.get(url("/registration")); |  | ||||||
| 				driver.findElement(By.id("username")).sendKeys(this.getUser()); |  | ||||||
| 				driver.findElement(By.id("password")).sendKeys("password"); |  | ||||||
| 				driver.findElement(By.id("matchingPassword")).sendKeys("password"); |  | ||||||
| 				driver.findElement(By.name("agree")).click(); |  | ||||||
| 				driver.findElement(By.className("btn-primary")).click(); |  | ||||||
| 			} |  | ||||||
| 		} catch (Exception e) { |  | ||||||
| 			System.err.println("Selenium test failed "+System.getProperty("webdriver.gecko.driver")+", message: "+e.getMessage()); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	@AfterEach |  | ||||||
| 	public void tearDown() { |  | ||||||
| 		if (null != driver) { |  | ||||||
| 			driver.close(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	@Test |  | ||||||
| 	public void sqlInjection() { |  | ||||||
| 		 |  | ||||||
| 		if (null==driver) return; |  | ||||||
|  |  | ||||||
| 		driver.get(url("/start.mvc#lesson/SqlInjection.lesson")); |  | ||||||
| 		driver.get(url("/start.mvc#lesson/SqlInjection.lesson/1")); |  | ||||||
| 		driver.findElement(By.id("restart-lesson-button")).click(); |  | ||||||
| 		driver.get(url("/start.mvc#lesson/SqlInjection.lesson/0")); |  | ||||||
| 		driver.get(url("/start.mvc#lesson/SqlInjection.lesson/1")); |  | ||||||
| 		driver.findElement(By.name("query")).sendKeys(SqlInjectionLessonIntegrationTest.sql_2); |  | ||||||
| 		driver.findElement(By.name("query")).submit(); |  | ||||||
|  |  | ||||||
| 		driver.get(url("/start.mvc#lesson/SqlInjection.lesson/2")); |  | ||||||
| 		driver.findElements(By.name("query")).get(1).sendKeys(SqlInjectionLessonIntegrationTest.sql_3); |  | ||||||
| 		driver.findElements(By.name("query")).get(1).submit(); |  | ||||||
|  |  | ||||||
| 		driver.get(url("/start.mvc#lesson/SqlInjection.lesson/3")); |  | ||||||
| 		driver.findElements(By.name("query")).get(2).sendKeys(SqlInjectionLessonIntegrationTest.sql_4_drop); |  | ||||||
| 		driver.findElements(By.name("query")).get(2).submit(); |  | ||||||
|  |  | ||||||
| 		driver.get(url("/start.mvc#lesson/SqlInjection.lesson/3")); |  | ||||||
| 		driver.findElements(By.name("query")).get(2).clear(); |  | ||||||
| 		driver.findElements(By.name("query")).get(2).sendKeys(SqlInjectionLessonIntegrationTest.sql_4_add); |  | ||||||
| 		driver.findElements(By.name("query")).get(2).submit(); |  | ||||||
| 		driver.findElements(By.name("query")).get(2).clear(); |  | ||||||
| 		driver.findElements(By.name("query")).get(2).sendKeys(SqlInjectionLessonIntegrationTest.sql_4_drop); |  | ||||||
| 		driver.findElements(By.name("query")).get(2).submit(); |  | ||||||
|  |  | ||||||
| 		driver.get(url("/start.mvc#lesson/SqlInjection.lesson/4")); |  | ||||||
| 		driver.findElements(By.name("query")).get(3).sendKeys(SqlInjectionLessonIntegrationTest.sql_5); |  | ||||||
| 		driver.findElements(By.name("query")).get(3).submit(); |  | ||||||
|  |  | ||||||
| 		driver.get(url("/start.mvc#lesson/SqlInjection.lesson/8")); |  | ||||||
| 		driver.findElement(By.name("account")).sendKeys("Smith'"); |  | ||||||
| 		driver.findElement(By.name("operator")).sendKeys("OR"); |  | ||||||
| 		driver.findElement(By.name("injection")).sendKeys("'1'='1"); |  | ||||||
| 		driver.findElement(By.name("Get Account Info")).click(); |  | ||||||
|  |  | ||||||
| 		driver.get(url("/start.mvc#lesson/SqlInjection.lesson/9")); |  | ||||||
| 		driver.findElement(By.name("userid")).sendKeys(SqlInjectionLessonIntegrationTest.sql_10_userid); |  | ||||||
| 		driver.findElement(By.name("login_count")).sendKeys(SqlInjectionLessonIntegrationTest.sql_10_login_count); |  | ||||||
| 		driver.findElements(By.name("Get Account Info")).get(1).click(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user