├── java-selenium-code.md ├── todo-web-application └── src │ ├── main │ ├── resources │ │ ├── static │ │ │ ├── less │ │ │ │ ├── mixins.less │ │ │ │ └── variables.less │ │ │ ├── .gitignore │ │ │ ├── vendor │ │ │ │ ├── font-awesome │ │ │ │ │ ├── less │ │ │ │ │ │ ├── extras.less │ │ │ │ │ │ ├── screen-reader.less │ │ │ │ │ │ ├── fixed-width.less │ │ │ │ │ │ ├── larger.less │ │ │ │ │ │ ├── list.less │ │ │ │ │ │ ├── core.less │ │ │ │ │ │ ├── stacked.less │ │ │ │ │ │ ├── font-awesome.less │ │ │ │ │ │ ├── bordered-pulled.less │ │ │ │ │ │ ├── spinning.less │ │ │ │ │ │ ├── rotated-flipped.less │ │ │ │ │ │ ├── path.less │ │ │ │ │ │ ├── animated.less │ │ │ │ │ │ └── mixins.less │ │ │ │ │ ├── scss │ │ │ │ │ │ ├── _fixed-width.scss │ │ │ │ │ │ ├── _screen-reader.scss │ │ │ │ │ │ ├── _larger.scss │ │ │ │ │ │ ├── _list.scss │ │ │ │ │ │ ├── _core.scss │ │ │ │ │ │ ├── font-awesome.scss │ │ │ │ │ │ ├── _stacked.scss │ │ │ │ │ │ ├── _bordered-pulled.scss │ │ │ │ │ │ ├── _spinning.scss │ │ │ │ │ │ ├── _rotated-flipped.scss │ │ │ │ │ │ ├── _path.scss │ │ │ │ │ │ ├── _animated.scss │ │ │ │ │ │ ├── _extras.scss │ │ │ │ │ │ └── _mixins.scss │ │ │ │ │ ├── fonts │ │ │ │ │ │ ├── FontAwesome.otf │ │ │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ │ │ └── fontawesome-webfont.woff2 │ │ │ │ │ └── HELP-US-OUT.txt │ │ │ │ ├── datatables │ │ │ │ │ ├── images │ │ │ │ │ │ ├── favicon.ico │ │ │ │ │ │ ├── sort_asc.png │ │ │ │ │ │ ├── sort_both.png │ │ │ │ │ │ ├── sort_desc.png │ │ │ │ │ │ ├── Sorting icons.psd │ │ │ │ │ │ ├── sort_asc_disabled.png │ │ │ │ │ │ └── sort_desc_disabled.png │ │ │ │ │ ├── js │ │ │ │ │ │ ├── dataTables.bootstrap.min.js │ │ │ │ │ │ ├── dataTables.bootstrap4.min.js │ │ │ │ │ │ ├── dataTables.foundation.min.js │ │ │ │ │ │ ├── dataTables.material.min.js │ │ │ │ │ │ ├── dataTables.semanticui.min.js │ │ │ │ │ │ ├── dataTables.uikit.min.js │ │ │ │ │ │ └── dataTables.jqueryui.min.js │ │ │ │ │ └── css │ │ │ │ │ │ ├── dataTables.material.min.css │ │ │ │ │ │ ├── dataTables.foundation.min.css │ │ │ │ │ │ ├── dataTables.semanticui.min.css │ │ │ │ │ │ └── dataTables.material.css │ │ │ │ ├── bootstrap │ │ │ │ │ └── fonts │ │ │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ │ │ │ └── glyphicons-halflings-regular.woff2 │ │ │ │ ├── morrisjs │ │ │ │ │ └── morris.css │ │ │ │ ├── metisMenu │ │ │ │ │ ├── metisMenu.min.css │ │ │ │ │ ├── metisMenu.css │ │ │ │ │ └── metisMenu.min.js │ │ │ │ ├── datatables-plugins │ │ │ │ │ └── dataTables.bootstrap.min.js │ │ │ │ └── flot │ │ │ │ │ └── jquery.flot.symbol.js │ │ │ ├── pages │ │ │ │ ├── frames-example.html │ │ │ │ └── sortable.html │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── dist │ │ │ │ └── js │ │ │ │ │ ├── sb-admin-2.min.js │ │ │ │ │ └── sb-admin-2.js │ │ │ ├── LICENSE │ │ │ ├── bower.json │ │ │ ├── js │ │ │ │ └── sb-admin-2.js │ │ │ └── README.md │ │ ├── application.properties │ │ └── data.sql │ ├── webapp │ │ └── WEB-INF │ │ │ └── jsp │ │ │ ├── file-upload-successful.jsp │ │ │ ├── error.jsp │ │ │ ├── welcome.jsp │ │ │ ├── common │ │ │ ├── footer.jspf │ │ │ ├── header.jspf │ │ │ └── navigation.jspf │ │ │ ├── login.jsp │ │ │ ├── todo.jsp │ │ │ └── list-todos.jsp │ └── java │ │ └── com │ │ └── in28minutes │ │ └── springboot │ │ └── web │ │ ├── SpringBootFirstWebApplication.java │ │ ├── controller │ │ ├── LogoutController.java │ │ ├── WelcomeController.java │ │ ├── ErrorController.java │ │ ├── FileUploadController.java │ │ └── LoginController.java │ │ ├── service │ │ ├── LoginService.java │ │ ├── TodoRepository.java │ │ └── TodoService.java │ │ └── model │ │ └── Todo.java │ └── test │ └── java │ └── com │ └── in28minutes │ └── springboot │ └── web │ └── SpringBootFirstWebApplicationTests.java ├── html-basics ├── in28minutes-logo.png ├── 1-first-html.html ├── style.css ├── 5-nesting-and-more.html ├── 4-miscellaneous.html ├── 3-tables.html ├── 2-second-html.html └── 6-form.html ├── web-driver-4-data-driven-tests ├── src │ └── test │ │ ├── resources │ │ ├── login-data.csv │ │ └── login-data.xlsx │ │ └── java │ │ └── com │ │ └── in28minutes │ │ └── datadriventests │ │ ├── SuccessfulLoginBasicTest.java │ │ ├── UnSuccessfulLoginBasicTest.java │ │ ├── UnSuccessfulLoginDataDrivenBasicTest.java │ │ ├── UnSuccessfulLoginDataDrivenLevel1Test.java │ │ ├── ExcelReadUtil.java │ │ ├── LoginDataProviderCompleteTest.java │ │ └── LoginDataProviderCompleteExcelTest.java └── pom.xml ├── testng-basics ├── src │ └── test │ │ └── java │ │ └── com │ │ ├── in28minutes │ │ └── test │ │ │ └── testng │ │ │ ├── MultipleBrowserTest.java │ │ │ ├── FirstSeleniumTestNgTest.java │ │ │ └── FirstTestngTest.java │ │ └── example │ │ └── tests │ │ ├── FacebookLogin.java │ │ └── GoogleSearchForIn28minutes.java ├── testng.xml └── pom.xml ├── .gitignore ├── web-driver-5-page-object-model ├── src │ └── test │ │ └── java │ │ └── com │ │ └── in28minutes │ │ └── pageobjects │ │ └── updatetodo │ │ ├── WelcomePage.java │ │ ├── ListTodoPage.java │ │ ├── TodoPage.java │ │ ├── LoginPage.java │ │ ├── UpdateTodoBasicTest5AfterExercises.java │ │ ├── UpdateTodoBasicTest.java │ │ ├── UpdateTodoBasicTest1BeforePageObjects.java │ │ ├── UpdateTodoBasicTest3AfterListTodoPage.java │ │ └── UpdateTodoBasicTest2AfterLoginPage.java └── pom.xml ├── web-driver-3-cross-browser-framework ├── testng.xml ├── src │ └── test │ │ └── java │ │ └── com │ │ └── in28minutes │ │ └── selenium │ │ └── crossbrowser │ │ └── framework │ │ └── CrossBrowserFrameworkTest.java └── pom.xml ├── web-driver-2-more-scenarios ├── testng.xml ├── src │ └── test │ │ └── java │ │ └── com │ │ └── in28minutes │ │ └── webdriver │ │ ├── scenarios │ │ ├── framework │ │ │ └── TableReader.java │ │ ├── TakesScreenshotTest.java │ │ ├── FramesTest.java │ │ ├── RunJavaScriptTest.java │ │ ├── JavaScriptAlertTest.java │ │ ├── ReadTablesTest.java │ │ ├── PlayingWithScreenWindowTest.java │ │ ├── ActionsBasicTest.java │ │ └── NewWindowTest.java │ │ └── basics │ │ └── AbstractChromeWebDriverTest.java └── pom.xml ├── web-driver-1-basics ├── src │ └── test │ │ └── java │ │ └── com │ │ └── in28minutes │ │ └── webdriver │ │ ├── basics │ │ ├── WebDriverBasicsLocatorsWithClassTest.java │ │ ├── AbstractChromeWebDriverTest.java │ │ ├── WebDriverBasicsLocatorsWithLinkTextTest.java │ │ ├── form │ │ │ ├── FormElementTextTest.java │ │ │ └── FormElementSelectTest.java │ │ ├── WebDriverBasicsLocatorsWithXPathSelectorTest.java │ │ ├── WebDriverBasicsLocatorsPerformanceTest.java │ │ ├── WebDriverBasicsLocatorsWithTagTest.java │ │ ├── WebDriverBasicsLocatorsWithIdTest.java │ │ ├── WebDriverBasicsLocatorsWithCSSSelectorTest.java │ │ └── WebDriverBasicsLocatorsWithNameTest.java │ │ └── login │ │ ├── StaticLoginTest.java │ │ └── FirstWebApplicationLoginTest.java └── pom.xml ├── junit-basics ├── pom.xml └── src │ └── test │ └── java │ └── com │ ├── in28minutes │ └── tests │ │ ├── FirstSeleniumJUnitTest.java │ │ └── FirstJUnitTest.java │ └── example │ └── tests │ ├── GoogleSearchForIn28minutes.java │ ├── FacebookLogin.java │ └── FacebookLoginDummy.java └── web-driver-6-stand-alone-and-grid ├── pom.xml └── src └── test └── java └── com └── in28minutes ├── SeleniumStandAloneTest.java └── SeleniumHubTest.java /java-selenium-code.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bower_components -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/extras.less: -------------------------------------------------------------------------------- 1 | // Extras 2 | // -------------------------- 3 | -------------------------------------------------------------------------------- /todo-web-application/src/main/webapp/WEB-INF/jsp/file-upload-successful.jsp: -------------------------------------------------------------------------------- 1 |
2 | ${message} 3 |
-------------------------------------------------------------------------------- /html-basics/in28minutes-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/html-basics/in28minutes-logo.png -------------------------------------------------------------------------------- /web-driver-4-data-driven-tests/src/test/resources/login-data.csv: -------------------------------------------------------------------------------- 1 | in28minutes,dummy,true 2 | adam,adam,false 3 | adam,adam@123,true 4 | eve,eve,false 5 | eve,eve@123,true 6 | in28minutes,eve@123,false -------------------------------------------------------------------------------- /html-basics/1-first-html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Learn Selenium and HTML 4 | 5 | 6 | 7 | This is the body of the page. 8 | 9 | -------------------------------------------------------------------------------- /web-driver-4-data-driven-tests/src/test/resources/login-data.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/web-driver-4-data-driven-tests/src/test/resources/login-data.xlsx -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/screen-reader.less: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { .sr-only(); } 5 | .sr-only-focusable { .sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.mvc.view.prefix=/WEB-INF/jsp/ 2 | spring.mvc.view.suffix=.jsp 3 | logging.level.org.springframework.web=INFO 4 | 5 | spring.jpa.show-sql=true 6 | spring.h2.console.enabled=true -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { @include sr-only(); } 5 | .sr-only-focusable { @include sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/pages/frames-example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/datatables/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/datatables/images/favicon.ico -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/datatables/images/sort_asc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/datatables/images/sort_asc.png -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/datatables/images/sort_both.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/datatables/images/sort_both.png -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/datatables/images/sort_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/datatables/images/sort_desc.png -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/datatables/images/Sorting icons.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/datatables/images/Sorting icons.psd -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/datatables/images/sort_asc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/datatables/images/sort_asc_disabled.png -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/datatables/images/sort_desc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/datatables/images/sort_desc_disabled.png -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /todo-web-application/src/main/webapp/WEB-INF/jsp/error.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf"%> 2 | <%@ include file="common/navigation.jspf"%> 3 |
4 | An exception occurred! Please contact Support! 5 |
6 | <%@ include file="common/footer.jspf"%> -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/automation-testing-with-java-and-selenium/HEAD/todo-web-application/src/main/resources/static/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /todo-web-application/src/main/webapp/WEB-INF/jsp/welcome.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf"%> 2 | <%@ include file="common/navigation.jspf"%> 3 |
4 | Welcome ${name}!! Click here to manage your 5 | todo's. 6 |
7 | <%@ include file="common/footer.jspf"%> -------------------------------------------------------------------------------- /html-basics/style.css: -------------------------------------------------------------------------------- 1 | label { 2 | font-size: 16px; 3 | color: #111111; 4 | } 5 | 6 | input, textarea, select { 7 | background-color: antiquewhite; 8 | } 9 | 10 | fieldset { 11 | border: 0px; 12 | padding: 20px; 13 | background-color: #EEFFFF; 14 | } 15 | 16 | ul { 17 | background-color: #EEFFEE; 18 | } 19 | 20 | li { 21 | color: #666666; 22 | } 23 | -------------------------------------------------------------------------------- /testng-basics/src/test/java/com/in28minutes/test/testng/MultipleBrowserTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.test.testng; 2 | 3 | import org.testng.annotations.Parameters; 4 | import org.testng.annotations.Test; 5 | 6 | public class MultipleBrowserTest { 7 | 8 | @Parameters("browser") 9 | @Test 10 | public void runInBrowser(String browser) { 11 | System.out.println(browser); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SB Admin 2 6 | 9 | 10 | 11 | Go to /pages/index.html 12 | 13 | 14 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/HELP-US-OUT.txt: -------------------------------------------------------------------------------- 1 | I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project, 2 | Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome, 3 | comprehensive icon sets or copy and paste your own. 4 | 5 | Please. Check it out. 6 | 7 | -Dave Gandy 8 | -------------------------------------------------------------------------------- /todo-web-application/src/main/webapp/WEB-INF/jsp/common/footer.jspf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/less/variables.less: -------------------------------------------------------------------------------- 1 | // Variables 2 | 3 | @gray-darker: lighten(#000, 13.5%); 4 | @gray-dark: lighten(#000, 20%); 5 | @gray: lighten(#000, 33.5%); 6 | @gray-light: lighten(#000, 60%); 7 | @gray-lighter: lighten(#000, 93.5%); 8 | @gray-lightest: lighten(#000, 97.25%); 9 | @brand-primary: #428bca; 10 | @brand-success: #5cb85c; 11 | @brand-info: #5bc0de; 12 | @brand-warning: #f0ad4e; 13 | @brand-danger: #d9534f; 14 | 15 | -------------------------------------------------------------------------------- /todo-web-application/src/main/webapp/WEB-INF/jsp/common/header.jspf: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 2 | <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> 3 | <%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> 4 | 5 | 6 | 7 | 8 | First Web Application 9 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /todo-web-application/src/main/webapp/WEB-INF/jsp/login.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf"%> 2 | <%@ include file="common/navigation.jspf"%> 3 |
4 |
${errorMessage}
5 |
6 | Name : Password : 8 |
9 |
10 | <%@ include file="common/footer.jspf"%> -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | *.cmd 21 | *.classpath 22 | *.settings 23 | *.project 24 | *.mvn 25 | mvnw 26 | target 27 | *.DS_Store 28 | test-output 29 | 30 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 31 | hs_err_pid* 32 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/morrisjs/morris.css: -------------------------------------------------------------------------------- 1 | .morris-hover{position:absolute;z-index:1000}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255,255,255,0.8);border:solid 2px rgba(230,230,230,0.8);font-family:sans-serif;font-size:12px;text-align:center}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0} 2 | .morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0} 3 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /web-driver-5-page-object-model/src/test/java/com/in28minutes/pageobjects/updatetodo/WelcomePage.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.pageobjects.updatetodo; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | 6 | public class WelcomePage { 7 | 8 | private WebDriver driver; 9 | 10 | public WelcomePage(WebDriver driver) { 11 | super(); 12 | this.driver = driver; 13 | } 14 | 15 | public void clickTodosLink() { 16 | driver.findElement(By.linkText("Click here")).click(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /todo-web-application/src/test/java/com/in28minutes/springboot/web/SpringBootFirstWebApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringBootFirstWebApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | insert into TODO 2 | values(10001, 'Learn Automation Testing', false, sysdate() + 365, 'in28minutes'); 3 | insert into TODO 4 | values(10002, 'Become a Tech Guru', false, sysdate() + 366, 'in28minutes'); 5 | insert into TODO 6 | values(10003, 'Learn to Dance', false, sysdate() + 367, 'in28minutes'); 7 | 8 | insert into TODO 9 | values(10004, 'Make Great Courses', false, sysdate() - 2, 'ranga'); 10 | insert into TODO 11 | values(10005, 'Reach 1 Million Learners', false, sysdate() - 3, 'ranga'); -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: @fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: (-@fa-li-width + (4em / 14)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /web-driver-3-cross-browser-framework/testng.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "animated"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | @import "screen-reader"; 19 | -------------------------------------------------------------------------------- /html-basics/5-nesting-and-more.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Learn Selenium and HTML 5 4 | 5 | 6 | 7 |
8 | 9 |

The great thing about HTML is that its simple to learn. 10 | This is the first page we have created 11 |

12 | 13 |

This is the second thing we have learnt - Here is the link to it

14 | 15 |
16 | 17 | -------------------------------------------------------------------------------- /todo-web-application/src/main/java/com/in28minutes/springboot/web/SpringBootFirstWebApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.ComponentScan; 6 | 7 | @SpringBootApplication 8 | @ComponentScan("com.in28minutes.springboot.web") 9 | public class SpringBootFirstWebApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(SpringBootFirstWebApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /web-driver-2-more-scenarios/testng.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /todo-web-application/src/main/java/com/in28minutes/springboot/web/controller/LogoutController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import javax.servlet.http.HttpSession; 4 | 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestMethod; 8 | 9 | @Controller 10 | public class LogoutController { 11 | @RequestMapping(value = "/logout", method = RequestMethod.GET) 12 | public String logOut(HttpSession session) { 13 | session.invalidate(); 14 | return "redirect:/login"; 15 | } 16 | } -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables.less"; 7 | @import "mixins.less"; 8 | @import "path.less"; 9 | @import "core.less"; 10 | @import "larger.less"; 11 | @import "fixed-width.less"; 12 | @import "list.less"; 13 | @import "bordered-pulled.less"; 14 | @import "animated.less"; 15 | @import "rotated-flipped.less"; 16 | @import "stacked.less"; 17 | @import "icons.less"; 18 | @import "screen-reader.less"; 19 | -------------------------------------------------------------------------------- /todo-web-application/src/main/java/com/in28minutes/springboot/web/service/LoginService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.service; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | @Service 6 | public class LoginService { 7 | 8 | public boolean validateUser(String userid, String password) { 9 | // in28minutes, dummy 10 | 11 | 12 | return (userid.equalsIgnoreCase("in28minutes") 13 | && password.equalsIgnoreCase("dummy")) 14 | || (userid.equalsIgnoreCase("adam") 15 | && password.equalsIgnoreCase("adam@123")) 16 | || (userid.equalsIgnoreCase("eve") 17 | && password.equalsIgnoreCase("eve@123")) 18 | ; 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /todo-web-application/src/main/java/com/in28minutes/springboot/web/service/TodoRepository.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.service; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import com.in28minutes.springboot.web.model.Todo; 8 | 9 | public interface TodoRepository extends JpaRepository{ 10 | List findByUserOrderByTargetDateAsc(String user); 11 | 12 | //service.retrieveTodos(name) 13 | 14 | //service.deleteTodo(id); 15 | //service.retrieveTodo(id) 16 | //service.updateTodo(todo) 17 | //service.addTodo(getLoggedInUserName(model), todo.getDesc(), todo.getTargetDate(),false); 18 | } 19 | -------------------------------------------------------------------------------- /todo-web-application/src/main/webapp/WEB-INF/jsp/common/navigation.jspf: -------------------------------------------------------------------------------- 1 | 2 | 22 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .@{fa-css-prefix}-pull-left { float: left; } 11 | .@{fa-css-prefix}-pull-right { float: right; } 12 | 13 | .@{fa-css-prefix} { 14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .@{fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/spinning.less: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | @-webkit-keyframes fa-spin { 10 | 0% { 11 | -webkit-transform: rotate(0deg); 12 | transform: rotate(0deg); 13 | } 14 | 100% { 15 | -webkit-transform: rotate(359deg); 16 | transform: rotate(359deg); 17 | } 18 | } 19 | 20 | @keyframes fa-spin { 21 | 0% { 22 | -webkit-transform: rotate(0deg); 23 | transform: rotate(0deg); 24 | } 25 | 100% { 26 | -webkit-transform: rotate(359deg); 27 | transform: rotate(359deg); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .#{$fa-css-prefix}-pull-left { float: left; } 11 | .#{$fa-css-prefix}-pull-right { float: right; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .#{$fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /todo-web-application/src/main/java/com/in28minutes/springboot/web/controller/WelcomeController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.ui.ModelMap; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestMethod; 7 | import org.springframework.web.bind.annotation.SessionAttributes; 8 | 9 | @Controller 10 | @SessionAttributes("name") 11 | public class WelcomeController { 12 | 13 | @RequestMapping(value = "/welcome", method = RequestMethod.GET) 14 | public String showWelcomePage(ModelMap model) { 15 | if(!model.containsAttribute("name")) 16 | return "redirect:/login"; 17 | 18 | return "welcome"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .@{fa-css-prefix}-rotate-90, 15 | :root .@{fa-css-prefix}-rotate-180, 16 | :root .@{fa-css-prefix}-rotate-270, 17 | :root .@{fa-css-prefix}-flip-horizontal, 18 | :root .@{fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/_spinning.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | @-webkit-keyframes fa-spin { 10 | 0% { 11 | -webkit-transform: rotate(0deg); 12 | transform: rotate(0deg); 13 | } 14 | 100% { 15 | -webkit-transform: rotate(359deg); 16 | transform: rotate(359deg); 17 | } 18 | } 19 | 20 | @keyframes fa-spin { 21 | 0% { 22 | -webkit-transform: rotate(0deg); 23 | transform: rotate(0deg); 24 | } 25 | 100% { 26 | -webkit-transform: rotate(359deg); 27 | transform: rotate(359deg); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /html-basics/4-miscellaneous.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Learn a few things in HTML 4 | 5 | 6 | 7 | 8 |
    9 |
  1. First HTML Page
  2. 10 |
  3. Go to in28minutes
  4. 11 |
  5. Second HTML Page
  6. 12 |
13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /testng-basics/testng.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "startbootstrap-sb-admin-2", 3 | "title": "SB Admin 2", 4 | "version": "3.3.7+1", 5 | "homepage": "http://startbootstrap.com/template-overviews/sb-admin-2", 6 | "author": "Start Bootstrap", 7 | "license": { 8 | "type": "MIT", 9 | "url": "https://github.com/BlackrockDigital/startbootstrap/blob/gh-pages/LICENSE" 10 | }, 11 | "devDependencies": { 12 | "browser-sync": "^2.13.0", 13 | "gulp": "^3.9.1", 14 | "gulp-clean-css": "^2.0.10", 15 | "gulp-header": "^1.8.7", 16 | "gulp-less": "^3.1.0", 17 | "gulp-rename": "^1.2.2", 18 | "gulp-uglify": "^1.5.4" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git://github.com/BlackrockDigital/startbootstrap-sb-admin-2.git" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /web-driver-2-more-scenarios/src/test/java/com/in28minutes/webdriver/scenarios/framework/TableReader.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.scenarios.framework; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.WebElement; 6 | 7 | public class TableReader { 8 | private WebDriver driver; 9 | private String id; 10 | private WebElement tbody; 11 | 12 | public TableReader(WebDriver driver, String id) { 13 | this.driver = driver; 14 | this.id = id; 15 | tbody = driver.findElement(By.cssSelector("#" 16 | + id 17 | + " > tbody")); 18 | } 19 | 20 | public String getData(int row, int col) { 21 | return tbody.findElement(By.cssSelector("tr:nth-child(" 22 | + row 23 | + ") > td:nth-child(" 24 | + col 25 | + ")")).getText(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .#{$fa-css-prefix}-rotate-90, 15 | :root .#{$fa-css-prefix}-rotate-180, 16 | :root .#{$fa-css-prefix}-rotate-270, 17 | :root .#{$fa-css-prefix}-flip-horizontal, 18 | :root .#{$fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /todo-web-application/src/main/java/com/in28minutes/springboot/web/controller/ErrorController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | import org.springframework.web.servlet.ModelAndView; 9 | 10 | @Controller("error") 11 | public class ErrorController { 12 | 13 | @ExceptionHandler(Exception.class) 14 | public ModelAndView handleException 15 | (HttpServletRequest request, Exception ex){ 16 | ModelAndView mv = new ModelAndView(); 17 | 18 | mv.addObject("exception", ex.getLocalizedMessage()); 19 | mv.addObject("url", request.getRequestURL()); 20 | 21 | mv.setViewName("error"); 22 | return mv; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/metisMenu/metisMenu.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | * metismenu - v1.1.3 3 | * Easy menu jQuery plugin for Twitter Bootstrap 3 4 | * https://github.com/onokumus/metisMenu 5 | * 6 | * Made by Osman Nuri Okumus 7 | * Under MIT License 8 | */ 9 | 10 | .arrow{float:right;line-height:1.42857}.glyphicon.arrow:before{content:"\e079"}.active>a>.glyphicon.arrow:before{content:"\e114"}.fa.arrow:before{content:"\f104"}.active>a>.fa.arrow:before{content:"\f107"}.plus-times{float:right}.fa.plus-times:before{content:"\f067"}.active>a>.fa.plus-times{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.plus-minus{float:right}.fa.plus-minus:before{content:"\f067"}.active>a>.fa.plus-minus:before{content:"\f068"} -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}'); 7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'), 8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'), 9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'), 10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'), 11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/dist/js/sb-admin-2.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Start Bootstrap - SB Admin 2 v3.3.7+1 (http://startbootstrap.com/template-overviews/sb-admin-2) 3 | * Copyright 2013-2016 Start Bootstrap 4 | * Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap/blob/gh-pages/LICENSE) 5 | */ 6 | $(function(){$("#side-menu").metisMenu()}),$(function(){$(window).bind("load resize",function(){var i=50,n=this.window.innerWidth>0?this.window.innerWidth:this.screen.width;n<768?($("div.navbar-collapse").addClass("collapse"),i=100):$("div.navbar-collapse").removeClass("collapse");var e=(this.window.innerHeight>0?this.window.innerHeight:this.screen.height)-1;e-=i,e<1&&(e=1),e>i&&$("#page-wrapper").css("min-height",e+"px")});for(var i=window.location,n=$("ul.nav a").filter(function(){return this.href==i}).addClass("active").parent();;){if(!n.is("li"))break;n=n.parent().addClass("in").parent()}}); -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'), 9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /web-driver-5-page-object-model/src/test/java/com/in28minutes/pageobjects/updatetodo/ListTodoPage.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.pageobjects.updatetodo; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | 6 | public class ListTodoPage { 7 | 8 | private WebDriver driver; 9 | 10 | public ListTodoPage(WebDriver driver) { 11 | super(); 12 | this.driver = driver; 13 | } 14 | 15 | //get description for id 16 | //desc- + id 17 | public String getDescription(String id) { 18 | return driver.findElement(By.id("desc-" + id)).getText(); 19 | } 20 | 21 | //get target date for id 22 | public String getTargetDate(String id) { 23 | return driver.findElement(By.id("targetdate-" + id)).getText(); 24 | } 25 | 26 | //click update for a id 27 | public void clickUpdateFor(String id) { 28 | driver.findElement(By.id("update-" + id)).click(); 29 | } 30 | 31 | //delete a id 32 | 33 | } 34 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/animated.less: -------------------------------------------------------------------------------- 1 | // Animated Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | .@{fa-css-prefix}-pulse { 10 | -webkit-animation: fa-spin 1s infinite steps(8); 11 | animation: fa-spin 1s infinite steps(8); 12 | } 13 | 14 | @-webkit-keyframes fa-spin { 15 | 0% { 16 | -webkit-transform: rotate(0deg); 17 | transform: rotate(0deg); 18 | } 19 | 100% { 20 | -webkit-transform: rotate(359deg); 21 | transform: rotate(359deg); 22 | } 23 | } 24 | 25 | @keyframes fa-spin { 26 | 0% { 27 | -webkit-transform: rotate(0deg); 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | -webkit-transform: rotate(359deg); 32 | transform: rotate(359deg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/_animated.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | .#{$fa-css-prefix}-pulse { 10 | -webkit-animation: fa-spin 1s infinite steps(8); 11 | animation: fa-spin 1s infinite steps(8); 12 | } 13 | 14 | @-webkit-keyframes fa-spin { 15 | 0% { 16 | -webkit-transform: rotate(0deg); 17 | transform: rotate(0deg); 18 | } 19 | 100% { 20 | -webkit-transform: rotate(359deg); 21 | transform: rotate(359deg); 22 | } 23 | } 24 | 25 | @keyframes fa-spin { 26 | 0% { 27 | -webkit-transform: rotate(0deg); 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | -webkit-transform: rotate(359deg); 32 | transform: rotate(359deg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /todo-web-application/src/main/webapp/WEB-INF/jsp/todo.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf" %> 2 | <%@ include file="common/navigation.jspf" %> 3 |
4 | 5 | 6 |
7 | Description 8 | 10 | 11 |
12 | 13 |
14 | Target Date 15 | 17 | 18 |
19 | 20 |
21 |
22 | <%@ include file="common/footer.jspf" %> -------------------------------------------------------------------------------- /web-driver-2-more-scenarios/src/test/java/com/in28minutes/webdriver/scenarios/TakesScreenshotTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.scenarios; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import org.apache.commons.io.FileUtils; 7 | import org.openqa.selenium.By; 8 | import org.openqa.selenium.OutputType; 9 | import org.openqa.selenium.TakesScreenshot; 10 | import org.testng.annotations.Test; 11 | 12 | import com.in28minutes.webdriver.basics.AbstractChromeWebDriverTest; 13 | 14 | public class TakesScreenshotTest extends AbstractChromeWebDriverTest { 15 | 16 | @Test 17 | public void testFrames() throws IOException { 18 | 19 | driver.get("http://localhost:8080/pages/frames-example.html"); 20 | 21 | //Operations 22 | 23 | File screenshot = ((TakesScreenshot)driver) 24 | .getScreenshotAs(OutputType.FILE); 25 | 26 | FileUtils.copyFile(screenshot, 27 | new File("./target/" + driver + "-screenshot.png")); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /todo-web-application/src/main/java/com/in28minutes/springboot/web/controller/FileUploadController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.ui.Model; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestMethod; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | import org.springframework.web.bind.annotation.SessionAttributes; 9 | import org.springframework.web.multipart.MultipartFile; 10 | 11 | @Controller 12 | @SessionAttributes("name") 13 | public class FileUploadController { 14 | 15 | @RequestMapping(value = "/fileupload", method = RequestMethod.POST) 16 | public String uploadFile(@RequestParam("file") MultipartFile file, Model model) { 17 | model.addAttribute("message", "You successfully uploaded " + file.getOriginalFilename() + "!"); 18 | return "file-upload-successful"; 19 | 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /web-driver-2-more-scenarios/src/test/java/com/in28minutes/webdriver/scenarios/FramesTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.scenarios; 2 | 3 | import org.openqa.selenium.By; 4 | import org.testng.annotations.Test; 5 | 6 | import com.in28minutes.webdriver.basics.AbstractChromeWebDriverTest; 7 | 8 | public class FramesTest extends AbstractChromeWebDriverTest { 9 | 10 | @Test 11 | public void testFrames() { 12 | driver.get("http://localhost:8080/pages/frames-example.html"); 13 | 14 | driver.switchTo().frame(0); 15 | 16 | System.out.println( 17 | "0 - " + driver.findElement(By.tagName("h1")).getText() 18 | );//0 - Frames Example Left 19 | 20 | //org.openqa.selenium.NoSuchFrameException: no such frame 21 | //driver.switchTo().frame(1); 22 | 23 | driver.switchTo().parentFrame(); 24 | 25 | driver.switchTo().frame(1); 26 | 27 | System.out.println( 28 | "1 - " + driver.findElement(By.tagName("h1")).getText() 29 | );//1 - Frames Example Right 30 | 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /web-driver-1-basics/src/test/java/com/in28minutes/webdriver/basics/WebDriverBasicsLocatorsWithClassTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.basics; 2 | 3 | import static org.testng.Assert.assertEquals; 4 | 5 | import java.util.List; 6 | 7 | import org.openqa.selenium.By; 8 | import org.openqa.selenium.WebElement; 9 | import org.testng.annotations.Test; 10 | 11 | public class WebDriverBasicsLocatorsWithClassTest extends AbstractChromeWebDriverTest{ 12 | 13 | @Test 14 | public void testTitle() { 15 | driver.get("http://localhost:8080/pages/index.html"); 16 | WebElement title = driver.findElement(By.className("navbar-brand")); 17 | assertEquals(title.getText(), "SB Admin v2.0"); 18 | } 19 | 20 | //huge 21 | @Test 22 | public void testHugeTextElements() { 23 | driver.get("http://localhost:8080/pages/index.html"); 24 | List hugeElements = driver.findElements(By.className("huge")); 25 | for(WebElement element: hugeElements) { 26 | System.out.println(element.getText()); 27 | } 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /web-driver-2-more-scenarios/src/test/java/com/in28minutes/webdriver/scenarios/RunJavaScriptTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.scenarios; 2 | 3 | import java.io.IOException; 4 | 5 | import org.openqa.selenium.JavascriptExecutor; 6 | import org.testng.annotations.Test; 7 | 8 | import com.in28minutes.webdriver.basics.AbstractChromeWebDriverTest; 9 | 10 | public class RunJavaScriptTest extends AbstractChromeWebDriverTest { 11 | 12 | @Test 13 | public void testRunningOfJavaScript() throws IOException { 14 | 15 | driver.get("http://localhost:8080/pages/tables.html"); 16 | 17 | JavascriptExecutor js = (JavascriptExecutor)driver; 18 | 19 | String title = (String)js.executeScript("return document.title;"); 20 | 21 | sleep(3); 22 | 23 | js.executeScript("window.scrollBy(0,200)"); 24 | 25 | sleep(3); 26 | 27 | js.executeScript("window.scrollBy(0,200)"); 28 | 29 | sleep(3); 30 | 31 | js.executeScript("window.scrollBy(0,200)"); 32 | 33 | sleep(3); 34 | System.out.println(title); 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /web-driver-2-more-scenarios/src/test/java/com/in28minutes/webdriver/scenarios/JavaScriptAlertTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.scenarios; 2 | 3 | import org.openqa.selenium.Alert; 4 | import org.openqa.selenium.By; 5 | import org.testng.annotations.Test; 6 | 7 | import com.in28minutes.webdriver.basics.AbstractChromeWebDriverTest; 8 | 9 | public class JavaScriptAlertTest extends AbstractChromeWebDriverTest { 10 | 11 | @Test 12 | public void testForAlert() { 13 | driver.get("http://localhost:8080/pages/notifications.html"); 14 | driver.findElement(By.id("alertButton")).click(); 15 | 16 | //org.openqa.selenium.UnhandledAlertException: 17 | //unexpected alert open: {Alert text : Enter Something} 18 | //driver.findElement(By.id("modalButton")).click(); 19 | 20 | Alert alertQuestion = driver.switchTo().alert(); 21 | alertQuestion.sendKeys("Some Message"); 22 | alertQuestion.accept(); 23 | 24 | Alert alertMessage = driver.switchTo().alert(); 25 | System.out.println(alertMessage.getText()); 26 | alertMessage.accept(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /web-driver-1-basics/src/test/java/com/in28minutes/webdriver/basics/AbstractChromeWebDriverTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.basics; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.chrome.ChromeDriver; 5 | import org.testng.annotations.AfterTest; 6 | import org.testng.annotations.BeforeTest; 7 | 8 | import io.github.bonigarcia.wdm.WebDriverManager; 9 | 10 | public abstract class AbstractChromeWebDriverTest { 11 | 12 | protected WebDriver driver; 13 | 14 | public AbstractChromeWebDriverTest() { 15 | super(); 16 | } 17 | 18 | @BeforeTest 19 | public void beforeTest() { 20 | //Download the web driver executable 21 | WebDriverManager.chromedriver().setup(); 22 | 23 | //Create a instance of your web driver - chrome 24 | driver = new ChromeDriver(); 25 | } 26 | 27 | @AfterTest 28 | public void afterTest() { 29 | driver.quit(); 30 | } 31 | 32 | public void sleep(int seconds) { 33 | try { 34 | Thread.sleep(seconds * 1000); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /web-driver-4-data-driven-tests/src/test/java/com/in28minutes/datadriventests/SuccessfulLoginBasicTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.datadriventests; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.chrome.ChromeDriver; 7 | import org.testng.annotations.Test; 8 | 9 | import io.github.bonigarcia.wdm.WebDriverManager; 10 | 11 | public class SuccessfulLoginBasicTest { 12 | 13 | @Test 14 | public void testLoginWithIn28Minutes() { 15 | WebDriverManager.chromedriver().setup(); 16 | WebDriver driver = new ChromeDriver(); 17 | driver.get("http://localhost:8080/login"); 18 | driver.findElement(By.id("name")).sendKeys("in28minutes"); 19 | WebElement passwordElement = driver.findElement(By.id("password")); 20 | passwordElement.sendKeys("dummy"); 21 | passwordElement.submit(); 22 | // driver.findElement(By.id("submit")).click(); 23 | 24 | // welcome-message 25 | System.out.println(driver.findElement(By.id("welcome-message")).getText()); 26 | driver.quit(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/pages/sortable.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | sortable demo 6 | 8 | 9 | 10 | 11 | 26 | 27 | 28 | 29 |

Play with these

30 |
    31 |
  • HTML
  • 32 |
  • CSS
  • 33 |
  • JQuery
  • 34 |
  • XPath
  • 35 |
  • Selenium
  • 36 |
  • Java
  • 37 |
  • Design
  • 38 |
  • Framework
  • 39 |
40 | 41 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /web-driver-1-basics/src/test/java/com/in28minutes/webdriver/login/StaticLoginTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.login; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebElement; 5 | import org.testng.annotations.Test; 6 | 7 | import com.in28minutes.webdriver.basics.AbstractChromeWebDriverTest; 8 | 9 | public class StaticLoginTest extends AbstractChromeWebDriverTest{ 10 | 11 | @Test 12 | public void login() { 13 | driver.get("http://localhost:8080/pages/login.html"); 14 | 15 | sleep(5); 16 | 17 | WebElement emailElement = driver.findElement(By.name("email")); 18 | emailElement.sendKeys("in28minutes@gmail.com"); 19 | 20 | sleep(2); 21 | 22 | WebElement passwordElement = driver.findElement(By.name("password")); 23 | passwordElement.sendKeys("dummy"); 24 | 25 | sleep(2); 26 | 27 | WebElement loginElement = driver.findElement(By.tagName("a")); 28 | loginElement.click(); 29 | 30 | sleep(2); 31 | 32 | //http://localhost:8080/pages/index.html 33 | System.out.println(driver.getCurrentUrl()); 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /todo-web-application/src/main/webapp/WEB-INF/jsp/list-todos.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf"%> 2 | <%@ include file="common/navigation.jspf"%> 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 23 | 25 | 26 | 27 | 28 |
Your todos are
DescriptionTarget Date
${todo.desc}UpdateDelete
29 |
30 | Add a Todo 31 |
32 |
33 | 34 | <%@ include file="common/footer.jspf"%> -------------------------------------------------------------------------------- /web-driver-5-page-object-model/src/test/java/com/in28minutes/pageobjects/updatetodo/TodoPage.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.pageobjects.updatetodo; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | 7 | public class TodoPage { 8 | 9 | private WebDriver driver; 10 | 11 | public TodoPage(WebDriver driver) { 12 | super(); 13 | this.driver = driver; 14 | } 15 | 16 | @FindBy(id="desc") 17 | private WebElement description; 18 | 19 | @FindBy(id="targetDate") 20 | private WebElement targetDate; 21 | 22 | @FindBy(id="save") 23 | private WebElement saveButton; 24 | 25 | public void enterDescription(String desc) { 26 | description.clear(); 27 | description.sendKeys(desc); 28 | } 29 | 30 | public void enterTargetDate(String date) { 31 | targetDate.clear(); 32 | targetDate.sendKeys(date); 33 | } 34 | 35 | public void submit() { 36 | saveButton.submit(); 37 | } 38 | 39 | public void enterDetailsAndSubmit(String desc,String targetDate) { 40 | enterDescription(desc); 41 | enterTargetDate(targetDate); 42 | submit(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /web-driver-2-more-scenarios/src/test/java/com/in28minutes/webdriver/basics/AbstractChromeWebDriverTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.basics; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.chrome.ChromeDriver; 7 | import org.testng.annotations.AfterTest; 8 | import org.testng.annotations.BeforeTest; 9 | 10 | import io.github.bonigarcia.wdm.WebDriverManager; 11 | 12 | public abstract class AbstractChromeWebDriverTest { 13 | 14 | protected WebDriver driver; 15 | 16 | public AbstractChromeWebDriverTest() { 17 | super(); 18 | } 19 | 20 | @BeforeTest 21 | public void beforeTest() { 22 | //Download the web driver executable 23 | WebDriverManager.chromedriver().setup(); 24 | 25 | //Create a instance of your web driver - chrome 26 | driver = new ChromeDriver(); 27 | } 28 | 29 | @AfterTest 30 | public void afterTest() { 31 | driver.quit(); 32 | } 33 | 34 | public void sleep(int seconds) { 35 | try { 36 | Thread.sleep(seconds * 1000); 37 | } catch (InterruptedException e) { 38 | e.printStackTrace(); 39 | } 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2018 Blackrock Digital LLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /web-driver-5-page-object-model/src/test/java/com/in28minutes/pageobjects/updatetodo/LoginPage.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.pageobjects.updatetodo; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | 7 | public class LoginPage { 8 | 9 | private WebDriver driver; 10 | 11 | public LoginPage(WebDriver driver) { 12 | super(); 13 | driver.get("http://localhost:8080/login"); 14 | this.driver = driver; 15 | } 16 | 17 | //Name Text Box 18 | @FindBy(id="name") 19 | WebElement name; 20 | 21 | //Password Text Box 22 | @FindBy(id="password") 23 | WebElement password; 24 | 25 | //Submit Button 26 | @FindBy(id="submit") 27 | WebElement submitButton; 28 | 29 | //enterName 30 | public void enterName(String nameToEnter) { 31 | name.sendKeys(nameToEnter); 32 | } 33 | 34 | //enterPassword 35 | public void enterPassword(String passwordToEnter) { 36 | password.sendKeys(passwordToEnter); 37 | } 38 | 39 | //submit 40 | public void submit() { 41 | submitButton.submit(); 42 | } 43 | 44 | public void login(String name, String password) { 45 | enterName(name); 46 | enterPassword(password); 47 | submit(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /web-driver-4-data-driven-tests/src/test/java/com/in28minutes/datadriventests/UnSuccessfulLoginBasicTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.datadriventests; 2 | 3 | import static org.testng.Assert.assertEquals; 4 | 5 | import org.openqa.selenium.By; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.WebElement; 8 | import org.openqa.selenium.chrome.ChromeDriver; 9 | import org.testng.annotations.Test; 10 | 11 | import io.github.bonigarcia.wdm.WebDriverManager; 12 | 13 | public class UnSuccessfulLoginBasicTest { 14 | 15 | @Test 16 | public void testUnsuccessfulLoginWithIn28Minutes() { 17 | WebDriverManager.chromedriver().setup(); 18 | WebDriver driver = new ChromeDriver(); 19 | driver.get("http://localhost:8080/login"); 20 | driver.findElement(By.id("name")).sendKeys("in28minutes"); 21 | WebElement passwordElement = driver.findElement(By.id("password")); 22 | passwordElement.sendKeys(""); 23 | passwordElement.submit(); 24 | // driver.findElement(By.id("submit")).click(); 25 | 26 | // welcome-message 27 | String errorMessageText = driver.findElement(By.id("error-message")).getText(); 28 | System.out.println(errorMessageText); 29 | assertEquals(errorMessageText,"Invalid Credentials"); 30 | driver.quit(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /web-driver-1-basics/src/test/java/com/in28minutes/webdriver/login/FirstWebApplicationLoginTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.login; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebElement; 5 | import org.testng.annotations.Test; 6 | 7 | import com.in28minutes.webdriver.basics.AbstractChromeWebDriverTest; 8 | 9 | public class FirstWebApplicationLoginTest extends AbstractChromeWebDriverTest{ 10 | 11 | @Test 12 | public void login() { 13 | driver.get("http://localhost:8080/login"); 14 | 15 | sleep(5); 16 | 17 | WebElement nameElement = driver.findElement(By.name("name")); 18 | nameElement.sendKeys("in28minutes"); 19 | 20 | sleep(2); 21 | 22 | WebElement passwordElement = driver.findElement(By.id("password")); 23 | passwordElement.sendKeys("dummy"); 24 | 25 | sleep(2); 26 | 27 | WebElement submitElement = driver.findElement(By.id("submit")); 28 | submitElement.click(); 29 | 30 | sleep(2); 31 | 32 | WebElement welcomeMessageElement = 33 | driver.findElement(By.id("welcome-message")); 34 | 35 | 36 | 37 | //Welcome in28minutes!! Click here to manage your todo's. 38 | System.out.println(welcomeMessageElement.getText()); 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "startbootstrap-sb-admin-2", 3 | "homepage": "http://startbootstrap.com/template-overviews/sb-admin-2/", 4 | "version": "3.3.7+1", 5 | "authors": [ 6 | "David Miller" 7 | ], 8 | "description": "A free, open source, Bootstrap admin theme created by Start Bootstrap", 9 | "keywords": [ 10 | "bootstrap", 11 | "theme" 12 | ], 13 | "license": "MIT", 14 | "ignore": [ 15 | "**/.*", 16 | "node_modules", 17 | "bower_components", 18 | "test", 19 | "tests", 20 | "pages", 21 | "index.html", 22 | "/js" 23 | ], 24 | "main": [ 25 | "dist/css/sb-admin-2.css", 26 | "dist/css/sb-admin-2.min.css", 27 | "dist/js/sb-admin-2.js", 28 | "dist/js/sb-admin-2.min.js" 29 | ], 30 | "dependencies": { 31 | "bootstrap": "~3.3.7", 32 | "datatables": "~1.10.4", 33 | "datatables-plugins": "~1.0.1", 34 | "flot": "~0.8.3", 35 | "font-awesome": "~4.6.3", 36 | "holderjs": "~2.4.1", 37 | "metisMenu": "~1.1.3", 38 | "morrisjs": "~0.5.1", 39 | "datatables-responsive": "1.0.6", 40 | "bootstrap-social": "~4.8.0", 41 | "flot.tooltip": "~0.8.4" 42 | }, 43 | "resolutions": { 44 | "font-awesome": "~4.6.3" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /web-driver-1-basics/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.in28minutes 5 | web-driver-1-basics 6 | 0.0.1-SNAPSHOT 7 | 8 | 9 | 10 | 11 | org.seleniumhq.selenium 12 | selenium-java 13 | 3.13.0 14 | test 15 | 16 | 17 | 18 | 19 | io.github.bonigarcia 20 | webdrivermanager 21 | 2.2.4 22 | test 23 | 24 | 25 | 26 | ch.qos.logback 27 | logback-classic 28 | 1.0.13 29 | test 30 | 31 | 32 | 33 | org.testng 34 | testng 35 | 6.14.3 36 | test 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /testng-basics/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.in28minutes 5 | testng-selenium-automation-tests 6 | 0.0.1-SNAPSHOT 7 | 8 | 9 | 10 | 11 | org.seleniumhq.selenium 12 | selenium-java 13 | 3.13.0 14 | test 15 | 16 | 17 | 18 | 19 | io.github.bonigarcia 20 | webdrivermanager 21 | 2.2.4 22 | test 23 | 24 | 25 | 26 | ch.qos.logback 27 | logback-classic 28 | 1.0.13 29 | test 30 | 31 | 32 | 33 | org.testng 34 | testng 35 | 6.14.3 36 | test 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /web-driver-5-page-object-model/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.in28minutes 5 | web-driver-5-page-objects-model 6 | 0.0.1-SNAPSHOT 7 | 8 | 9 | 10 | 11 | org.seleniumhq.selenium 12 | selenium-java 13 | 3.13.0 14 | test 15 | 16 | 17 | 18 | 19 | io.github.bonigarcia 20 | webdrivermanager 21 | 2.2.4 22 | test 23 | 24 | 25 | 26 | ch.qos.logback 27 | logback-classic 28 | 1.0.13 29 | test 30 | 31 | 32 | 33 | org.testng 34 | testng 35 | 6.14.3 36 | test 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/metisMenu/metisMenu.css: -------------------------------------------------------------------------------- 1 | /* 2 | * metismenu - v1.1.3 3 | * Easy menu jQuery plugin for Twitter Bootstrap 3 4 | * https://github.com/onokumus/metisMenu 5 | * 6 | * Made by Osman Nuri Okumus 7 | * Under MIT License 8 | */ 9 | .arrow { 10 | float: right; 11 | line-height: 1.42857; 12 | } 13 | 14 | .glyphicon.arrow:before { 15 | content: "\e079"; 16 | } 17 | 18 | .active > a > .glyphicon.arrow:before { 19 | content: "\e114"; 20 | } 21 | 22 | 23 | /* 24 | * Require Font-Awesome 25 | * http://fortawesome.github.io/Font-Awesome/ 26 | */ 27 | 28 | 29 | .fa.arrow:before { 30 | content: "\f104"; 31 | } 32 | 33 | .active > a > .fa.arrow:before { 34 | content: "\f107"; 35 | } 36 | 37 | .plus-times { 38 | float: right; 39 | } 40 | 41 | .fa.plus-times:before { 42 | content: "\f067"; 43 | } 44 | 45 | .active > a > .fa.plus-times { 46 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); 47 | -webkit-transform: rotate(45deg); 48 | -moz-transform: rotate(45deg); 49 | -ms-transform: rotate(45deg); 50 | -o-transform: rotate(45deg); 51 | transform: rotate(45deg); 52 | } 53 | 54 | .plus-minus { 55 | float: right; 56 | } 57 | 58 | .fa.plus-minus:before { 59 | content: "\f067"; 60 | } 61 | 62 | .active > a > .fa.plus-minus:before { 63 | content: "\f068"; 64 | } -------------------------------------------------------------------------------- /junit-basics/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | com.in28minutes 4 | junit-selenium-automation-tests 5 | 0.0.1-SNAPSHOT 6 | 7 | 8 | 9 | 10 | org.seleniumhq.selenium 11 | selenium-java 12 | 3.13.0 13 | test 14 | 15 | 16 | 17 | 18 | io.github.bonigarcia 19 | webdrivermanager 20 | 2.2.4 21 | test 22 | 23 | 24 | 25 | ch.qos.logback 26 | logback-classic 27 | 1.0.13 28 | test 29 | 30 | 31 | 32 | junit 33 | junit 34 | 4.12 35 | test 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /web-driver-6-stand-alone-and-grid/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | com.in28minutes 4 | web-driver-6-stand-alone-and-grid 5 | 0.0.1-SNAPSHOT 6 | 7 | 8 | 9 | org.seleniumhq.selenium 10 | selenium-java 11 | 3.13.0 12 | test 13 | 14 | 15 | 16 | 17 | io.github.bonigarcia 18 | webdrivermanager 19 | 2.2.4 20 | test 21 | 22 | 23 | 24 | ch.qos.logback 25 | logback-classic 26 | 1.0.13 27 | test 28 | 29 | 30 | 31 | org.testng 32 | testng 33 | 6.14.3 34 | test 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /web-driver-2-more-scenarios/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | com.in28minutes 4 | web-driver-2-more-scenarios 5 | 0.0.1-SNAPSHOT 6 | 7 | 8 | 9 | 10 | org.seleniumhq.selenium 11 | selenium-java 12 | 3.13.0 13 | test 14 | 15 | 16 | 17 | 18 | io.github.bonigarcia 19 | webdrivermanager 20 | 2.2.4 21 | test 22 | 23 | 24 | 25 | ch.qos.logback 26 | logback-classic 27 | 1.0.13 28 | test 29 | 30 | 31 | 32 | org.testng 33 | testng 34 | 6.14.3 35 | test 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /web-driver-1-basics/src/test/java/com/in28minutes/webdriver/basics/WebDriverBasicsLocatorsWithLinkTextTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.basics; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebElement; 5 | import org.testng.annotations.Test; 6 | 7 | public class WebDriverBasicsLocatorsWithLinkTextTest extends AbstractChromeWebDriverTest { 8 | 9 | @Test 10 | public void getIn28MinuteLinkAndClickIt() { 11 | driver.get("http://localhost:8080/login"); 12 | WebElement link = driver.findElement(By.linkText("in28Minutes")); 13 | System.out.println(link.getAttribute("href"));//http://www.in28minutes.com/ 14 | link.click(); 15 | System.out.println(driver.getCurrentUrl());// http://www.in28minutes.com/ 16 | } 17 | 18 | @Test 19 | public void getTableLinkAndClickIt() { 20 | driver.get("http://localhost:8080/pages/index.html"); 21 | WebElement link = driver.findElement(By.linkText("Tables")); 22 | System.out.println(link.getAttribute("href")); 23 | link.click(); 24 | System.out.println(driver.getCurrentUrl()); 25 | } 26 | 27 | @Test 28 | public void getSBAdminLinkAndClickIt() { 29 | driver.get("http://localhost:8080/pages/index.html"); 30 | WebElement link = driver.findElement(By.partialLinkText("SB Admin")); 31 | System.out.println(link.getAttribute("href")); 32 | link.click(); 33 | System.out.println(driver.getCurrentUrl()); 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/_extras.scss: -------------------------------------------------------------------------------- 1 | /* EXTRAS 2 | * -------------------------- */ 3 | 4 | /* Stacked and layered icon */ 5 | 6 | /* Animated rotating icon */ 7 | .#{$fa-css-prefix}-spin { 8 | -webkit-animation: spin 2s infinite linear; 9 | -moz-animation: spin 2s infinite linear; 10 | -o-animation: spin 2s infinite linear; 11 | animation: spin 2s infinite linear; 12 | } 13 | 14 | @-moz-keyframes spin { 15 | 0% { -moz-transform: rotate(0deg); } 16 | 100% { -moz-transform: rotate(359deg); } 17 | } 18 | @-webkit-keyframes spin { 19 | 0% { -webkit-transform: rotate(0deg); } 20 | 100% { -webkit-transform: rotate(359deg); } 21 | } 22 | @-o-keyframes spin { 23 | 0% { -o-transform: rotate(0deg); } 24 | 100% { -o-transform: rotate(359deg); } 25 | } 26 | @-ms-keyframes spin { 27 | 0% { -ms-transform: rotate(0deg); } 28 | 100% { -ms-transform: rotate(359deg); } 29 | } 30 | @keyframes spin { 31 | 0% { transform: rotate(0deg); } 32 | 100% { transform: rotate(359deg); } 33 | } 34 | 35 | 36 | // Icon rotations & flipping 37 | // ------------------------- 38 | 39 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 40 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 41 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 42 | 43 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 44 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 45 | -------------------------------------------------------------------------------- /web-driver-3-cross-browser-framework/src/test/java/com/in28minutes/selenium/crossbrowser/framework/CrossBrowserFrameworkTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.selenium.crossbrowser.framework; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.chrome.ChromeDriver; 5 | import org.openqa.selenium.firefox.FirefoxDriver; 6 | import org.testng.annotations.AfterTest; 7 | import org.testng.annotations.BeforeTest; 8 | import org.testng.annotations.Optional; 9 | import org.testng.annotations.Parameters; 10 | import org.testng.annotations.Test; 11 | 12 | import io.github.bonigarcia.wdm.WebDriverManager; 13 | 14 | public class CrossBrowserFrameworkTest { 15 | 16 | WebDriver driver = null; 17 | 18 | @Parameters("browser") 19 | @BeforeTest 20 | public void before(@Optional("chrome") String browser) { 21 | if(browser.equals("chrome")) { 22 | WebDriverManager.chromedriver().setup(); 23 | driver = new ChromeDriver(); 24 | } else if(browser.equals("firefox")){ 25 | WebDriverManager.firefoxdriver().setup(); 26 | driver = new FirefoxDriver(); 27 | } else { 28 | throw new RuntimeException("Does not support browser + " + browser); 29 | } 30 | } 31 | 32 | @Test 33 | public void launchTablesPage() { 34 | // Launch a web page 35 | driver.get("http://localhost:8080/pages/tables.html"); 36 | 37 | } 38 | 39 | @Test 40 | public void launchIndexPage() { 41 | // Launch a web page 42 | driver.get("http://localhost:8080/pages/index.html"); 43 | 44 | } 45 | 46 | @AfterTest 47 | public void afterTest() { 48 | driver.quit(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/js/sb-admin-2.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | $('#side-menu').metisMenu(); 3 | }); 4 | 5 | //Loads the correct sidebar on window load, 6 | //collapses the sidebar on window resize. 7 | // Sets the min-height of #page-wrapper to window size 8 | $(function() { 9 | $(window).bind("load resize", function() { 10 | var topOffset = 50; 11 | var width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width; 12 | if (width < 768) { 13 | $('div.navbar-collapse').addClass('collapse'); 14 | topOffset = 100; // 2-row-menu 15 | } else { 16 | $('div.navbar-collapse').removeClass('collapse'); 17 | } 18 | 19 | var height = ((this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height) - 1; 20 | height = height - topOffset; 21 | if (height < 1) height = 1; 22 | if (height > topOffset) { 23 | $("#page-wrapper").css("min-height", (height) + "px"); 24 | } 25 | }); 26 | 27 | var url = window.location; 28 | // var element = $('ul.nav a').filter(function() { 29 | // return this.href == url; 30 | // }).addClass('active').parent().parent().addClass('in').parent(); 31 | var element = $('ul.nav a').filter(function() { 32 | return this.href == url; 33 | }).addClass('active').parent(); 34 | 35 | while (true) { 36 | if (element.is('li')) { 37 | element = element.parent().addClass('in').parent(); 38 | } else { 39 | break; 40 | } 41 | } 42 | }); 43 | -------------------------------------------------------------------------------- /web-driver-3-cross-browser-framework/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.in28minutes 5 | web-driver-3-cross-browser-framework 6 | 0.0.1-SNAPSHOT 7 | 8 | 9 | 10 | 11 | org.seleniumhq.selenium 12 | selenium-java 13 | 3.13.0 14 | test 15 | 16 | 17 | 18 | 19 | io.github.bonigarcia 20 | webdrivermanager 21 | 2.2.4 22 | test 23 | 24 | 25 | 26 | ch.qos.logback 27 | logback-classic 28 | 1.0.13 29 | test 30 | 31 | 32 | 33 | org.testng 34 | testng 35 | 6.14.3 36 | test 37 | 38 | 39 | 40 | 41 | com.codeborne 42 | phantomjsdriver 43 | 1.4.4 44 | test 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /todo-web-application/src/main/java/com/in28minutes/springboot/web/controller/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.ui.ModelMap; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestMethod; 8 | import org.springframework.web.bind.annotation.RequestParam; 9 | import org.springframework.web.bind.annotation.SessionAttributes; 10 | 11 | import com.in28minutes.springboot.web.service.LoginService; 12 | 13 | @Controller 14 | @SessionAttributes("name") 15 | public class LoginController { 16 | 17 | @Autowired 18 | private LoginService service; 19 | 20 | @RequestMapping(value="/", method = RequestMethod.GET) 21 | public String rootPage(){ 22 | return "redirect:/login"; 23 | } 24 | 25 | @RequestMapping(value="/login", method = RequestMethod.GET) 26 | public String showLoginPage(ModelMap model){ 27 | if(model.containsAttribute("name")) 28 | return "redirect:/welcome"; 29 | return "login"; 30 | } 31 | 32 | @RequestMapping(value="/login", method = RequestMethod.POST) 33 | public String showWelcomePage(ModelMap model, @RequestParam String name, @RequestParam String password){ 34 | 35 | boolean isValidUser = service.validateUser(name, password); 36 | 37 | if (!isValidUser) { 38 | model.put("errorMessage", "Invalid Credentials"); 39 | return "login"; 40 | } 41 | 42 | model.addAttribute("name",name); 43 | return "redirect:/welcome"; 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /web-driver-1-basics/src/test/java/com/in28minutes/webdriver/basics/form/FormElementTextTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.basics.form; 2 | 3 | import static org.testng.Assert.assertEquals; 4 | 5 | import org.openqa.selenium.By; 6 | import org.openqa.selenium.WebElement; 7 | import org.testng.annotations.Test; 8 | 9 | import com.in28minutes.webdriver.basics.AbstractChromeWebDriverTest; 10 | 11 | public class FormElementTextTest extends AbstractChromeWebDriverTest { 12 | 13 | @Test 14 | public void readFromATextElement() { 15 | driver.get("http://localhost:8080/pages/forms.html"); 16 | assertEquals( 17 | driver.findElement(By.id("textElement")).getAttribute("value"), 18 | "in28minutes"); 19 | } 20 | 21 | @Test 22 | public void setASpecificValueIntoTextElement() { 23 | driver.get("http://localhost:8080/pages/forms.html"); 24 | WebElement textElement = driver.findElement(By.id("textElement")); 25 | sleep(4); 26 | textElement.clear(); 27 | textElement.sendKeys("NewValue"); 28 | sleep(4); 29 | } 30 | 31 | @Test 32 | public void writeAndReadAValueFromTextArea() { 33 | driver.get("http://localhost:8080/pages/forms.html"); 34 | 35 | WebElement textArea = driver.findElement(By.id("textAreaElement")); 36 | 37 | assertEquals(textArea.getAttribute("value"),""); 38 | sleep(4); 39 | textArea.clear(); 40 | textArea.sendKeys("FirstLine"); 41 | textArea.sendKeys("\n"); 42 | textArea.sendKeys("SecondLine"); 43 | sleep(4); 44 | System.out.println(textArea.getAttribute("value")); 45 | assertEquals(textArea.getAttribute("value"),"FirstLine\nSecondLine"); 46 | 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /web-driver-4-data-driven-tests/src/test/java/com/in28minutes/datadriventests/UnSuccessfulLoginDataDrivenBasicTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.datadriventests; 2 | 3 | import static org.testng.Assert.assertEquals; 4 | 5 | import org.openqa.selenium.By; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.WebElement; 8 | import org.openqa.selenium.chrome.ChromeDriver; 9 | import org.testng.annotations.DataProvider; 10 | import org.testng.annotations.Test; 11 | 12 | import io.github.bonigarcia.wdm.WebDriverManager; 13 | 14 | public class UnSuccessfulLoginDataDrivenBasicTest { 15 | 16 | //Create the Data Provider and give the data provider a name 17 | @DataProvider(name="user-ids-data-provider") 18 | public String[] userIdsDataProvider() { 19 | return new String[]{"in28minutes","adam","eve"}; 20 | } 21 | 22 | //Use the data provider 23 | @Test(dataProvider="user-ids-data-provider") 24 | public void testUnsuccessfulLoginWithIn28Minutes(String userId) { 25 | WebDriverManager.chromedriver().setup(); 26 | WebDriver driver = new ChromeDriver(); 27 | driver.get("http://localhost:8080/login"); 28 | driver.findElement(By.id("name")).sendKeys(userId); 29 | //driver.findElement(By.id("name")).sendKeys("in28minutes"); 30 | WebElement passwordElement = driver.findElement(By.id("password")); 31 | passwordElement.sendKeys(""); 32 | passwordElement.submit(); 33 | // driver.findElement(By.id("submit")).click(); 34 | 35 | // welcome-message 36 | String errorMessageText = driver.findElement(By.id("error-message")).getText(); 37 | System.out.println(errorMessageText); 38 | assertEquals(errorMessageText,"Invalid Credentials"); 39 | driver.quit(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /web-driver-6-stand-alone-and-grid/src/test/java/com/in28minutes/SeleniumStandAloneTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.chrome.ChromeDriver; 8 | import org.openqa.selenium.remote.DesiredCapabilities; 9 | import org.openqa.selenium.remote.RemoteWebDriver; 10 | import org.testng.annotations.Test; 11 | 12 | import io.github.bonigarcia.wdm.WebDriverManager; 13 | 14 | public class SeleniumStandAloneTest { 15 | 16 | @Test 17 | public void basic() { 18 | WebDriverManager.chromedriver().setup(); 19 | WebDriver driver = new ChromeDriver(); 20 | driver.get("http://localhost:8080/pages/index.html"); 21 | System.out.println(driver.getCurrentUrl()); 22 | System.out.println(driver.getTitle()); 23 | driver.quit(); 24 | } 25 | 26 | @Test 27 | public void standalone() throws MalformedURLException, InterruptedException { 28 | 29 | DesiredCapabilities capabilites = new DesiredCapabilities(); 30 | 31 | //chrome, firefox, htmlunit, internet explorer, iphone, opera 32 | capabilites.setBrowserName("chrome"); 33 | 34 | //WebDriverManager.chromedriver().setup(); 35 | //WebDriver driver = new ChromeDriver(); 36 | WebDriver remoteDriver = new RemoteWebDriver( 37 | new URL("http://localhost:4444/wd/hub"), capabilites); 38 | 39 | //RemoteWebDriver 40 | // Location of Standaloneserver 41 | // Which Browser? Which OS? => Capabilities 42 | 43 | remoteDriver.get("http://localhost:8080/pages/index.html"); 44 | System.out.println(remoteDriver.getCurrentUrl()); 45 | System.out.println(remoteDriver.getTitle()); 46 | Thread.sleep(15000); 47 | remoteDriver.quit(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /web-driver-2-more-scenarios/src/test/java/com/in28minutes/webdriver/scenarios/ReadTablesTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.scenarios; 2 | 3 | import java.io.IOException; 4 | 5 | import org.openqa.selenium.By; 6 | import org.openqa.selenium.JavascriptExecutor; 7 | import org.openqa.selenium.WebElement; 8 | import org.testng.annotations.Test; 9 | 10 | import com.in28minutes.webdriver.basics.AbstractChromeWebDriverTest; 11 | import com.in28minutes.webdriver.scenarios.framework.TableReader; 12 | 13 | public class ReadTablesTest extends AbstractChromeWebDriverTest { 14 | 15 | @Test 16 | public void testReadingOfTables() throws IOException { 17 | 18 | driver.get("http://localhost:8080/pages/tables.html"); 19 | 20 | TableReader reader = new TableReader(driver, "dataTables-example"); 21 | System.out.println(reader.getData(1,2)); 22 | System.out.println(reader.getData(2,2)); 23 | System.out.println(reader.getData(5,4)); 24 | System.out.println(reader.getData(6,3)); 25 | 26 | TableReader reader2 = new TableReader(driver, "dataTables-example-2"); 27 | System.out.println(reader2.getData(1, 2)); 28 | 29 | //1,2 30 | //2,3 31 | //WebElement tbody = driver.findElement(By.cssSelector("#dataTables-example > tbody")); 32 | 33 | //String t12 = tbody.findElement(By.cssSelector("tr:nth-child(1) > td:nth-child(2)")).getText(); 34 | 35 | //String t22 = tbody.findElement(By.cssSelector("tr:nth-child(2) > td:nth-child(2)")).getText(); 36 | 37 | //System.out.println(t12); 38 | //System.out.println(t22); 39 | 40 | //#dataTables-example > tbody > tr:nth-child(1) > td:nth-child(2) 41 | //#dataTables-example > tbody > tr:nth-child(2) > td:nth-child(2) 42 | //#dataTables-example > tbody > tr:nth-child(1) > td:nth-child(3) 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /web-driver-1-basics/src/test/java/com/in28minutes/webdriver/basics/WebDriverBasicsLocatorsWithXPathSelectorTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.basics; 2 | 3 | import static org.testng.Assert.assertEquals; 4 | 5 | import java.util.List; 6 | 7 | import org.openqa.selenium.By; 8 | import org.openqa.selenium.WebElement; 9 | import org.testng.annotations.Test; 10 | 11 | public class WebDriverBasicsLocatorsWithXPathSelectorTest extends AbstractChromeWebDriverTest{ 12 | 13 | @Test 14 | public void testXpathSelectorForaTableTd() { 15 | driver.get("http://localhost:8080/pages/tables.html"); 16 | //$x("//*[@id='dataTables-example']/tbody/tr[1]/td[2]") 17 | WebElement browserRow1 = driver.findElement(By.xpath("//*[@id='dataTables-example']/tbody/tr[1]/td[2]")); 18 | assertEquals(browserRow1.getText(), "Firefox 1.0"); 19 | } 20 | 21 | // $$("#dataTables-example > thead > tr > th:nth-child(2)") 22 | // [th.sorting]0: th.sortinglength: 1__proto__: Array(0) 23 | // $$("#dataTables-example > tbody > tr.gradeU.odd > td.sorting_1") 24 | // [td.sorting_1] 25 | 26 | @Test 27 | public void testXpathSelectorForSortingAndCheckingFirstRow() { 28 | 29 | // $x("//*[@id='dataTables-example']/thead/tr/th[2]") 30 | // [th.sorting]0: th.sortinglength: 1__proto__: Array(0) 31 | // $x("//*[@id='dataTables-example']/tbody/tr[1]/td[2]") 32 | // [td] 33 | 34 | driver.get("http://localhost:8080/pages/tables.html"); 35 | 36 | WebElement headerBrowser = driver.findElement 37 | (By.xpath( 38 | "//*[@id='dataTables-example']/thead/tr/th[2]")); 39 | 40 | headerBrowser.click(); 41 | 42 | WebElement element = driver.findElement 43 | (By.xpath( 44 | "//*[@id='dataTables-example']/tbody/tr[1]/td[2]")); 45 | 46 | assertEquals(element.getText(), "All others"); 47 | } 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /web-driver-4-data-driven-tests/src/test/java/com/in28minutes/datadriventests/UnSuccessfulLoginDataDrivenLevel1Test.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.datadriventests; 2 | 3 | import static org.testng.Assert.assertEquals; 4 | 5 | import org.openqa.selenium.By; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.WebElement; 8 | import org.openqa.selenium.chrome.ChromeDriver; 9 | import org.testng.annotations.DataProvider; 10 | import org.testng.annotations.Test; 11 | 12 | import io.github.bonigarcia.wdm.WebDriverManager; 13 | 14 | public class UnSuccessfulLoginDataDrivenLevel1Test { 15 | 16 | //Create the Data Provider and give the data provider a name 17 | @DataProvider(name="user-ids-passwords-data-provider") 18 | public String[][] userIdsAndPasswordsDataProvider() { 19 | return new String[][]{ 20 | {"in28minutes","in28minutes"}, 21 | {"adam","adam"}, 22 | {"eve","eve"}, 23 | }; 24 | } 25 | 26 | //Use the data provider 27 | @Test(dataProvider="user-ids-passwords-data-provider") 28 | public void testUnsuccessfulLoginWithIn28Minutes(String userId, String password) { 29 | WebDriverManager.chromedriver().setup(); 30 | WebDriver driver = new ChromeDriver(); 31 | driver.get("http://localhost:8080/login"); 32 | driver.findElement(By.id("name")).sendKeys(userId); 33 | //driver.findElement(By.id("name")).sendKeys("in28minutes"); 34 | WebElement passwordElement = driver.findElement(By.id("password")); 35 | passwordElement.sendKeys(password); 36 | passwordElement.submit(); 37 | // driver.findElement(By.id("submit")).click(); 38 | 39 | // welcome-message 40 | String errorMessageText = driver.findElement(By.id("error-message")).getText(); 41 | System.out.println(errorMessageText); 42 | assertEquals(errorMessageText,"Invalid Credentials"); 43 | driver.quit(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /web-driver-2-more-scenarios/src/test/java/com/in28minutes/webdriver/scenarios/PlayingWithScreenWindowTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.webdriver.scenarios; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.Dimension; 5 | import org.openqa.selenium.Point; 6 | import org.openqa.selenium.WebElement; 7 | import org.testng.annotations.Test; 8 | 9 | import com.in28minutes.webdriver.basics.AbstractChromeWebDriverTest; 10 | 11 | public class PlayingWithScreenWindowTest extends AbstractChromeWebDriverTest { 12 | 13 | @Test 14 | public void playingWithWindows() { 15 | driver.get("http://localhost:8080/pages/forms.html"); 16 | 17 | System.out.println(driver.manage().window().getPosition());//(22, 22) 18 | System.out.println(driver.manage().window().getSize());//(1200, 752) 19 | sleep(3); 20 | //failed to change window state to normal, current state is maximized 21 | driver.manage().window().setPosition(new Point(200,200)); 22 | sleep(3); 23 | driver.manage().window().setSize(new Dimension(200,200)); 24 | sleep(3); 25 | driver.manage().window().maximize(); 26 | sleep(3); 27 | driver.manage().window().fullscreen(); 28 | sleep(3); 29 | 30 | } 31 | 32 | @Test 33 | public void backForwardAndNavigation() { 34 | driver.get("http://localhost:8080/pages/forms.html"); 35 | sleep(3); 36 | driver.get("http://localhost:8080/pages/tables.html"); 37 | sleep(3); 38 | driver.get("http://localhost:8080/pages/login.html"); 39 | sleep(3); 40 | driver.get("http://localhost:8080/pages/index.html"); 41 | sleep(3); 42 | driver.navigate().back(); 43 | sleep(3); 44 | driver.navigate().back(); 45 | sleep(3); 46 | driver.navigate().back(); 47 | sleep(3); 48 | driver.navigate().forward(); 49 | sleep(3); 50 | driver.navigate().refresh(); 51 | sleep(3); 52 | driver.navigate().back(); 53 | sleep(3); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /html-basics/3-tables.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Learn Tables in HTML 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
Football PlayerGoalsCountry
Ronaldo10Portugal
Messi10Argentina
Player Name6Europe
Player Name 23Europe
Player Name 34Europe
44 | 45 | 46 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/dist/js/sb-admin-2.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Start Bootstrap - SB Admin 2 v3.3.7+1 (http://startbootstrap.com/template-overviews/sb-admin-2) 3 | * Copyright 2013-2016 Start Bootstrap 4 | * Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap/blob/gh-pages/LICENSE) 5 | */ 6 | $(function() { 7 | $('#side-menu').metisMenu(); 8 | }); 9 | 10 | //Loads the correct sidebar on window load, 11 | //collapses the sidebar on window resize. 12 | // Sets the min-height of #page-wrapper to window size 13 | $(function() { 14 | $(window).bind("load resize", function() { 15 | var topOffset = 50; 16 | var width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width; 17 | if (width < 768) { 18 | $('div.navbar-collapse').addClass('collapse'); 19 | topOffset = 100; // 2-row-menu 20 | } else { 21 | $('div.navbar-collapse').removeClass('collapse'); 22 | } 23 | 24 | var height = ((this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height) - 1; 25 | height = height - topOffset; 26 | if (height < 1) height = 1; 27 | if (height > topOffset) { 28 | $("#page-wrapper").css("min-height", (height) + "px"); 29 | } 30 | }); 31 | 32 | var url = window.location; 33 | // var element = $('ul.nav a').filter(function() { 34 | // return this.href == url; 35 | // }).addClass('active').parent().parent().addClass('in').parent(); 36 | var element = $('ul.nav a').filter(function() { 37 | return this.href == url; 38 | }).addClass('active').parent(); 39 | 40 | while (true) { 41 | if (element.is('li')) { 42 | element = element.parent().addClass('in').parent(); 43 | } else { 44 | break; 45 | } 46 | } 47 | }); 48 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | 14 | .fa-icon-rotate(@degrees, @rotation) { 15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})"; 16 | -webkit-transform: rotate(@degrees); 17 | -ms-transform: rotate(@degrees); 18 | transform: rotate(@degrees); 19 | } 20 | 21 | .fa-icon-flip(@horiz, @vert, @rotation) { 22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)"; 23 | -webkit-transform: scale(@horiz, @vert); 24 | -ms-transform: scale(@horiz, @vert); 25 | transform: scale(@horiz, @vert); 26 | } 27 | 28 | 29 | // Only display content to screen readers. A la Bootstrap 4. 30 | // 31 | // See: http://a11yproject.com/posts/how-to-hide-content/ 32 | 33 | .sr-only() { 34 | position: absolute; 35 | width: 1px; 36 | height: 1px; 37 | padding: 0; 38 | margin: -1px; 39 | overflow: hidden; 40 | clip: rect(0,0,0,0); 41 | border: 0; 42 | } 43 | 44 | // Use in conjunction with .sr-only to only display content when it's focused. 45 | // 46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 47 | // 48 | // Credit: HTML5 Boilerplate 49 | 50 | .sr-only-focusable() { 51 | &:active, 52 | &:focus { 53 | position: static; 54 | width: auto; 55 | height: auto; 56 | margin: 0; 57 | overflow: visible; 58 | clip: auto; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/metisMenu/metisMenu.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * metismenu - v1.1.3 3 | * Easy menu jQuery plugin for Twitter Bootstrap 3 4 | * https://github.com/onokumus/metisMenu 5 | * 6 | * Made by Osman Nuri Okumus 7 | * Under MIT License 8 | */ 9 | !function(a,b,c){function d(b,c){this.element=a(b),this.settings=a.extend({},f,c),this._defaults=f,this._name=e,this.init()}var e="metisMenu",f={toggle:!0,doubleTapToGo:!1};d.prototype={init:function(){var b=this.element,d=this.settings.toggle,f=this;this.isIE()<=9?(b.find("li.active").has("ul").children("ul").collapse("show"),b.find("li").not(".active").has("ul").children("ul").collapse("hide")):(b.find("li.active").has("ul").children("ul").addClass("collapse in"),b.find("li").not(".active").has("ul").children("ul").addClass("collapse")),f.settings.doubleTapToGo&&b.find("li.active").has("ul").children("a").addClass("doubleTapToGo"),b.find("li").has("ul").children("a").on("click."+e,function(b){return b.preventDefault(),f.settings.doubleTapToGo&&f.doubleTapToGo(a(this))&&"#"!==a(this).attr("href")&&""!==a(this).attr("href")?(b.stopPropagation(),void(c.location=a(this).attr("href"))):(a(this).parent("li").toggleClass("active").children("ul").collapse("toggle"),void(d&&a(this).parent("li").siblings().removeClass("active").children("ul.in").collapse("hide")))})},isIE:function(){for(var a,b=3,d=c.createElement("div"),e=d.getElementsByTagName("i");d.innerHTML="",e[0];)return b>4?b:a},doubleTapToGo:function(a){var b=this.element;return a.hasClass("doubleTapToGo")?(a.removeClass("doubleTapToGo"),!0):a.parent().children("ul").length?(b.find(".doubleTapToGo").removeClass("doubleTapToGo"),a.addClass("doubleTapToGo"),!1):void 0},remove:function(){this.element.off("."+e),this.element.removeData(e)}},a.fn[e]=function(b){return this.each(function(){var c=a(this);c.data(e)&&c.data(e).remove(),c.data(e,new d(this,b))}),this}}(jQuery,window,document); -------------------------------------------------------------------------------- /web-driver-4-data-driven-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.in28minutes 5 | web-driver-4-data-driven-tests 6 | 0.0.1-SNAPSHOT 7 | 8 | 9 | 10 | 11 | org.seleniumhq.selenium 12 | selenium-java 13 | 3.13.0 14 | test 15 | 16 | 17 | 18 | 19 | io.github.bonigarcia 20 | webdrivermanager 21 | 2.2.4 22 | test 23 | 24 | 25 | 26 | ch.qos.logback 27 | logback-classic 28 | 1.0.13 29 | test 30 | 31 | 32 | 33 | org.testng 34 | testng 35 | 6.14.3 36 | test 37 | 38 | 39 | 40 | 41 | 42 | com.opencsv 43 | opencsv 44 | 3.4 45 | test 46 | 47 | 48 | 49 | 50 | 51 | org.apache.poi 52 | poi 53 | 3.6 54 | test 55 | 56 | 57 | 58 | org.apache.poi 59 | poi-ooxml 60 | 3.6 61 | test 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/font-awesome/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | 14 | @mixin fa-icon-rotate($degrees, $rotation) { 15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})"; 16 | -webkit-transform: rotate($degrees); 17 | -ms-transform: rotate($degrees); 18 | transform: rotate($degrees); 19 | } 20 | 21 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)"; 23 | -webkit-transform: scale($horiz, $vert); 24 | -ms-transform: scale($horiz, $vert); 25 | transform: scale($horiz, $vert); 26 | } 27 | 28 | 29 | // Only display content to screen readers. A la Bootstrap 4. 30 | // 31 | // See: http://a11yproject.com/posts/how-to-hide-content/ 32 | 33 | @mixin sr-only { 34 | position: absolute; 35 | width: 1px; 36 | height: 1px; 37 | padding: 0; 38 | margin: -1px; 39 | overflow: hidden; 40 | clip: rect(0,0,0,0); 41 | border: 0; 42 | } 43 | 44 | // Use in conjunction with .sr-only to only display content when it's focused. 45 | // 46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 47 | // 48 | // Credit: HTML5 Boilerplate 49 | 50 | @mixin sr-only-focusable { 51 | &:active, 52 | &:focus { 53 | position: static; 54 | width: auto; 55 | height: auto; 56 | margin: 0; 57 | overflow: visible; 58 | clip: auto; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /html-basics/2-second-html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Learn Selenium and HTML - 2 4 | 5 | 6 | 7 |

Learning Automation Testing with Selenium and HTML

8 | 9 | I want to learn 10 | 11 |
    12 |
  • HTML
  • 13 |
  • CSS
  • 14 |
  • XPath
  • 15 |
  • CSS Selectors
  • 16 |
  • Selenium
  • 17 |
18 | 19 |
    20 |
  1. HTML
  2. 21 |
  3. CSS
  4. 22 |
  5. XPath
  6. 23 |
  7. CSS Selectors
  8. 24 |
  9. Selenium
  10. 25 |
26 | 27 | 28 |

Learning HTML and Selenium is awesome. The following steps are involved

29 | 30 |

HTML

31 |

First step is to learn HTML

32 | 33 |

CSS

34 |

Second step is to learn CSS

35 | 36 |

This is the body of the page.

37 |

Paragraph 2

38 |

Paragraph 3

39 | 40 |
Division 1
41 |
Division 2
42 |
Division 3
43 | 44 |

45 | Paragraph which will be displayed in bold. 46 |

47 | 48 |

49 | Paragraph which will be displayed in italicized. 50 |

51 | 52 |
53 | 54 |
Ranga says - You become a great automation tester by learning atleast for an hour every day
55 | 56 |
57 | 58 |

59 | Line1.
60 | Line2.
61 | Line3. 62 |

63 | 64 |
65 | 66 | fkjsaklfjalk 67 | fkjsaklfjalk 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /todo-web-application/src/main/resources/static/vendor/datatables-plugins/dataTables.bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | DataTables Bootstrap 3 integration 3 | ©2011-2014 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(){var f=function(c,b){c.extend(!0,b.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-6'i><'col-sm-6'p>>",renderer:"bootstrap"});c.extend(b.ext.classes,{sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm"});b.ext.renderer.pageButton.bootstrap=function(g,f,p,k,h,l){var q=new b.Api(g),r=g.oClasses,i=g.oLanguage.oPaginate,d,e,o=function(b,f){var j,m,n,a,k=function(a){a.preventDefault(); 6 | c(a.currentTarget).hasClass("disabled")||q.page(a.data.action).draw(!1)};j=0;for(m=f.length;j",{"class":r.sPageButton+" "+ 7 | e,"aria-controls":g.sTableId,tabindex:g.iTabIndex,id:0===p&&"string"===typeof a?g.sTableId+"_"+a:null}).append(c("",{href:"#"}).html(d)).appendTo(b),g.oApi._fnBindAction(n,{action:a},k))}};o(c(f).empty().html('