├── .gitignore
├── src
└── main
│ ├── resources
│ ├── images
│ │ ├── cancel.png
│ │ ├── inspect.png
│ │ ├── refresh.png
│ │ └── wisard.png
│ └── license
│ │ └── license.txt
│ └── java
│ └── objectivetester
│ ├── RichElement.java
│ ├── UserInterface.java
│ ├── Const.java
│ ├── Theme.java
│ ├── DefaultWriter.java
│ ├── TestWriter.java
│ ├── Test5Writer.java
│ ├── ScriptWriter.java
│ ├── JsWriter.java
│ ├── EventListener.java
│ ├── BrowserDriver.java
│ ├── Wisard.form
│ └── Wisard.java
├── LICENSE
├── nb-configuration.xml
├── README.md
├── nbactions.xml
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /nbproject/
--------------------------------------------------------------------------------
/src/main/resources/images/cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ObjectiveTester/wisard/HEAD/src/main/resources/images/cancel.png
--------------------------------------------------------------------------------
/src/main/resources/images/inspect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ObjectiveTester/wisard/HEAD/src/main/resources/images/inspect.png
--------------------------------------------------------------------------------
/src/main/resources/images/refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ObjectiveTester/wisard/HEAD/src/main/resources/images/refresh.png
--------------------------------------------------------------------------------
/src/main/resources/images/wisard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ObjectiveTester/wisard/HEAD/src/main/resources/images/wisard.png
--------------------------------------------------------------------------------
/src/main/java/objectivetester/RichElement.java:
--------------------------------------------------------------------------------
1 | package objectivetester;
2 |
3 | /**
4 | *
5 | * @author steve
6 | */
7 | public class RichElement {
8 |
9 | protected String method;
10 | protected String attribute;
11 |
12 | RichElement(String method, String attribute) {
13 | this.method = method;
14 | this.attribute = attribute;
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/objectivetester/UserInterface.java:
--------------------------------------------------------------------------------
1 | package objectivetester;
2 |
3 | /**
4 | *
5 | * @author Steve
6 | */
7 | interface UserInterface {
8 |
9 | void addItem(String type, Object stack, String name, String id, String value, Object element, Boolean displayed);
10 |
11 | void rescan();
12 |
13 | void abort();
14 |
15 | void finished();
16 |
17 | void addCode(String fragment);
18 |
19 | void insertCode(String fragment, int above);
20 |
21 | boolean alertResponse(String title);
22 |
23 | String enterValue(String title);
24 |
25 | String enterSelection(String title, String choices[]);
26 |
27 | void elementIdent(String message);
28 |
29 | void errorMessage(String message);
30 |
31 | String getCSSselectors();
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 - 2018 Steve Mellor
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 all
13 | 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 THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/src/main/resources/license/license.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 - 2018 Steve Mellor
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 |
--------------------------------------------------------------------------------
/nb-configuration.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
16 | ${project.basedir}/license
17 | true
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/main/java/objectivetester/Const.java:
--------------------------------------------------------------------------------
1 | package objectivetester;
2 |
3 | /**
4 | *
5 | * @author Steve
6 | */
7 | interface Const {
8 |
9 | //these are used internally to denote action and element type
10 | static final String CLICK = "click";
11 |
12 | static final String FIND = "find";
13 |
14 | static final String ASSERT = "assert";
15 |
16 | static final String IDENTIFY = "identify";
17 |
18 | static final String INVISIBLE = "(invisible) ";
19 |
20 | static final String PAGE = "page";
21 |
22 | static final String TITLE = "title";
23 |
24 | static final String BROWSER = "browser";
25 |
26 | static final String WINDOW = "other window";
27 |
28 | static final String CURRENT = "current focus";
29 |
30 | static final String COOKIE = "cookie";
31 |
32 | //the style to 'highlight' an element
33 | static final String HIGHLIGHT = "'color: yellow; font-weight: bold; border: 2px dotted red;'";
34 |
35 | //max text to put in a dialog box
36 | static final int MAX_SIZ = 2048;
37 |
38 | static final int POP_CLICK = 0;
39 |
40 | static final int POP_FIND = 1;
41 |
42 | static final int POP_ASSERT = 2;
43 |
44 | static final int POP_ID = 3;
45 |
46 | static final int TAB_ELEMENT = 0;
47 |
48 | static final int TAB_LOCATION = 1;
49 |
50 | static final int TAB_NAME = 2;
51 |
52 | static final int TAB_ID = 3;
53 |
54 | static final int TAB_VALUE = 4;
55 |
56 | static final int TAB_WEBELEMENT = 5;
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Wisard
2 | ======
3 |
4 | Web Internal Structure Action RecorDer - a webdriver based tool for creating Selenium tests
5 |
6 | Building Wisard
7 | ===============
8 |
9 | Clone or download the source code and either:
10 |
11 | Open the 'wisard' folder in NetBeans or your favourite IDE, and build it.
12 |
13 | Build a package from the command line with:
14 |
15 | mvn package
16 |
17 |
18 | Running Wisard
19 | ==============
20 |
21 | Once built, either double-click 'Wisard-1.6.jar' or start from the command line with:
22 |
23 | java -jar target/Wisard-1.6.jar
24 |
25 |
26 | Then enter a web URL and click the find icon
27 |
28 | Using Wisard
29 | ============
30 | Once a browser has opened and displayed your web page, all the useful elements of the page are displayed in left hand pane of the Wisard window. Wisard will try to momentarily highlight any element you click on. Right clicking an element allows you to interact with it by clicking it or verifying it's value, etc.
31 |
32 | As you set and verify element values, the right hand pane is updated with jUnit test cases. Alternately, Java statements can be generated to automate a web task. These can be copied and pasted into a file/your favourite IDE and then compiled and executed.
33 |
34 | Wisard can set and verify input elements, verify and click links and anchors, and verify image elements.
35 |
36 | Wisard can open and record scripts in 'Firefox', 'Chrome', 'Internet Explorer', 'Edge' and 'Safari', drivers are auto-downloaded by Selenium Manager, or can be manually overridden by setting the 'driver' path setting in the 'Settings' window, and downloading the correct drivers for your OS.
37 |
38 |
39 | Screenshots and more can be found here : http://objectivetester.github.io/wisard
40 |
--------------------------------------------------------------------------------
/src/main/java/objectivetester/Theme.java:
--------------------------------------------------------------------------------
1 | package objectivetester;
2 | import java.io.BufferedReader;
3 | import java.io.InputStreamReader;
4 | import com.sun.jna.platform.win32.Advapi32Util;
5 | import com.sun.jna.platform.win32.WinReg;
6 |
7 | public final class Theme
8 | {
9 | public static boolean light() {
10 | Boolean light = false;
11 | String os = System.getProperty("os.name").toLowerCase();
12 |
13 | if (os.contains("windows")) {
14 | if (Advapi32Util.registryGetValue(WinReg.HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\personalize", "AppsUseLightTheme").toString().contentEquals("1")) {
15 | light = true;
16 | }
17 | } else if (os.contains("mac")) {
18 | try {
19 | Runtime rt = Runtime.getRuntime();
20 | String[] commands = {"/usr/bin/defaults", "read", "-g", "AppleInterfaceStyle"};
21 | Process proc = rt.exec(commands);
22 | BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
23 | BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
24 | String s = null;
25 | while ((s = stdError.readLine()) != null) {
26 | light = true;
27 | }
28 |
29 | s = null;
30 | while ((s = stdInput.readLine()) != null) {
31 | if (s.equalsIgnoreCase("dark")) {
32 | light = false;
33 | }
34 |
35 | }
36 | } catch (Exception e) {
37 | //System.out.println(e);
38 | }
39 | }
40 |
41 | return light;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/nbactions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | run
5 |
6 | jar
7 |
8 |
9 | process-classes
10 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
11 |
12 |
13 | -classpath %classpath objectivetester.Wisard
14 | java
15 |
16 |
17 |
18 | debug
19 |
20 | jar
21 |
22 |
23 | process-classes
24 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
25 |
26 |
27 | -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath objectivetester.Wisard
28 | java
29 | true
30 |
31 |
32 |
33 | profile
34 |
35 | jar
36 |
37 |
38 | process-classes
39 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
40 |
41 |
42 | -classpath %classpath objectivetester.Wisard
43 | java
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | Wisard
5 | objectivetester
6 | Wisard
7 | 1.6
8 | jar
9 |
10 |
11 | org.seleniumhq.selenium
12 | selenium-java
13 | 4.10.0
14 |
15 |
16 | com.formdev
17 | flatlaf
18 | 2.6
19 |
20 |
21 | net.java.dev.jna
22 | jna-platform
23 | 5.13.0
24 |
25 |
26 |
27 | UTF-8
28 | 1.8
29 | 1.8
30 | -Xlint:unchecked
31 |
32 |
33 |
34 |
35 | org.apache.maven.plugins
36 | maven-compiler-plugin
37 | 3.11.0
38 |
39 | 1.8
40 | 1.8
41 |
42 |
43 |
44 | org.apache.maven.plugins
45 | maven-jar-plugin
46 | 3.3.0
47 |
48 |
49 | org.apache.maven.plugins
50 | maven-assembly-plugin
51 | 3.6.0
52 |
53 |
54 | jar-with-dependencies
55 |
56 |
57 |
58 | objectivetester.Wisard
59 |
60 |
61 | false
62 |
63 |
64 |
65 | package
66 |
67 | single
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/src/main/java/objectivetester/DefaultWriter.java:
--------------------------------------------------------------------------------
1 | package objectivetester;
2 |
3 | /**
4 | *
5 | * @author steve
6 | */
7 | public class DefaultWriter {
8 | //browsermodel calls this and it updates the generated code
9 |
10 | UserInterface ui;
11 | int footer = 0;
12 |
13 | void writeHeader(String url, String browser) {
14 | }
15 |
16 | void writeFindEvent(String method, String attribute) {
17 | ui.insertCode("\n //find:" + attribute + "\n"
18 | + " element = driver.findElement(By." + method + "(\"" + attribute + "\"));"
19 | + "", footer);
20 | }
21 |
22 | void writeClickEvent(String method, String attribute) {
23 | ui.insertCode("\n //click:" + attribute + "\n"
24 | + " driver.findElement(By." + method + "(\"" + attribute + "\")).click();"
25 | + "", footer);
26 | }
27 |
28 | void writeInputEvent(String data) {
29 | ui.insertCode("\n element.clear();\n"
30 | + " element.sendKeys(\"" + data + "\");"
31 | + "", footer);
32 | }
33 |
34 | void writeSelectEvent(String data) {
35 | ui.insertCode("\n selector = new Select(element);\n"
36 | + " selector.selectByVisibleText(\"" + data + "\");"
37 | + "", footer);
38 | }
39 |
40 | void writeInputjsEvent(String jsInput) {
41 | ui.insertCode("\n js.executeScript(\"" + jsInput + "\");"
42 | + "", footer);
43 | }
44 |
45 | void writeAlertClick(String question, boolean choice) {
46 | String action;
47 | if (choice) {
48 | action = " alert.accept();\n";
49 | } else {
50 | action = " alert.dismiss();\n";
51 | }
52 | ui.insertCode("\n //alert:" + question + "\n"
53 | + " alert = driver.switchTo().alert();\n"
54 | + action
55 | + "", footer);
56 | }
57 |
58 | void writeSwitchByIndex(int frame) {
59 | ui.insertCode("\n //switch to:" + frame + "\n"
60 | + " driver.switchTo().frame(" + frame + ");"
61 | + "", footer);
62 | }
63 |
64 | void writeSwitchBack() {
65 | ui.insertCode("\n //switch back\n"
66 | + " driver.switchTo().defaultContent();"
67 | + "", footer);
68 | }
69 |
70 | void writeSwitchWin(String title) {
71 | ui.insertCode("\n //switch to:" + title + "\n"
72 | + " switchWin(driver, \"" + title + "\");"
73 | + "", footer);
74 | }
75 |
76 | void writeVerifyElement(String value, String method) {
77 | if (value != null) {
78 | value = "\"" + value + "\"";
79 | }
80 |
81 | String line;
82 | switch (method) {
83 | case "gettext":
84 | line = " assertEquals(" + value + ",element.getText());";
85 | break;
86 | default:
87 | line = " assertEquals(" + value + ",element.getAttribute(\"" + method + "\"));";
88 | }
89 | ui.insertCode("\n //assert:" + value + "\n"
90 | + line
91 | + "", footer);
92 | }
93 |
94 | void writeVerifyPage(String value) {
95 | if (value != null) {
96 | value = "\"" + value + "\"";
97 | }
98 | ui.insertCode("\n //assert:" + value + "\n"
99 | + " assertEquals(" + value + ", driver.getTitle());"
100 | + "", footer);
101 | }
102 |
103 | void writeVerifyCookie(String name, String value) {
104 | ui.insertCode("\n //assert:" + value + "\n"
105 | + " assertEquals(\"" + value + "\", driver.manage().getCookieNamed(\"" + name + "\").getValue().toString());"
106 | + "", footer);
107 | }
108 |
109 | void comment(String text) {
110 | ui.insertCode("\n //" + text + "\n", footer);
111 | }
112 |
113 | void writeStart() {
114 | }
115 |
116 | void writeEnd() {
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/src/main/java/objectivetester/TestWriter.java:
--------------------------------------------------------------------------------
1 | package objectivetester;
2 |
3 | /**
4 | *
5 | * @author Steve
6 | */
7 | class TestWriter extends DefaultWriter {
8 | //browsermodel calls this and it updates the generated code
9 | //creates numbered junit test cases
10 |
11 | private int n;
12 |
13 | TestWriter(UserInterface ui) {
14 | this.n = 0;
15 | this.ui = ui;
16 | }
17 |
18 | @Override
19 | void writeHeader(String url, String browser) {
20 | String driverImport = "";
21 | String sysProp = "";
22 | String driverInit = "";
23 |
24 | switch (browser) {
25 |
26 | case "FF":
27 | driverImport = "import org.openqa.selenium.firefox.FirefoxDriver;\n";
28 | if (System.getProperty("webdriver.gecko.driver") != null) {
29 | sysProp = " System.setProperty(\"webdriver.gecko.driver\", \""+System.getProperty("webdriver.gecko.driver")+"\");\n";
30 | }
31 | driverInit = " driver = new FirefoxDriver();\n";
32 | break;
33 |
34 | case "CR":
35 | driverImport = "import org.openqa.selenium.chrome.ChromeDriver;\n";
36 | if (System.getProperty("webdriver.chrome.driver") != null) {
37 | sysProp = " System.setProperty(\"webdriver.chrome.driver\", \""+System.getProperty("webdriver.chrome.driver")+"\");\n";
38 | }
39 | driverInit = " driver = new ChromeDriver();\n";
40 | break;
41 |
42 | case "ED":
43 | driverImport = "import org.openqa.selenium.edge.EdgeDriver;\n";
44 | if (System.getProperty("webdriver.edge.driver") != null) {
45 | sysProp = " System.setProperty(\"webdriver.edge.driver\", \""+System.getProperty("webdriver.edge.driver")+"\");\n";
46 | }
47 | driverInit = " WebDriver driver = new EdgeDriver();\n";
48 | break;
49 |
50 | case "SA":
51 | driverImport = "import org.openqa.selenium.safari.SafariDriver;\n";
52 | driverInit = " driver = new SafariDriver();\n";
53 | break;
54 | }
55 |
56 | ui.addCode("import java.time.Duration;\n"
57 | + driverImport
58 | + "import org.openqa.selenium.JavascriptExecutor;\n"
59 | + "import org.openqa.selenium.WebDriver;\n"
60 | + "import org.openqa.selenium.WebElement;\n"
61 | + "import org.openqa.selenium.By;\n"
62 | + "import org.openqa.selenium.Alert;\n"
63 | + "import org.openqa.selenium.support.ui.Select;\n"
64 | + "import org.junit.After;\n"
65 | + "import org.junit.AfterClass;\n"
66 | + "import org.junit.Before;\n"
67 | + "import org.junit.BeforeClass;\n"
68 | + "import org.junit.Test;\n"
69 | + "import static org.junit.Assert.*;\n"
70 | + "import org.junit.FixMethodOrder;\n"
71 | + "import org.junit.runners.MethodSorters;\n\n"
72 | + "@FixMethodOrder(MethodSorters.NAME_ASCENDING)\n"
73 | + "public class RecordedTest {\n\n"
74 | + " public RecordedTest() {\n"
75 | + " }\n"
76 | + " WebElement element;\n"
77 | + " Alert alert;\n"
78 | + " Select selector;\n"
79 | + " static WebDriver driver;\n"
80 | + " static JavascriptExecutor js;\n\n"
81 | + " @BeforeClass\n"
82 | + " public static void setUpClass() {\n"
83 | + sysProp
84 | + driverInit
85 | + " js = (JavascriptExecutor) driver;\n"
86 | + " driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));\n"
87 | + " driver.manage().timeouts().scriptTimeout(Duration.ofSeconds(10));\n"
88 | + " driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));\n"
89 | + " driver.get(\"" + url + "\");\n"
90 | + " }\n\n"
91 | + " @AfterClass\n"
92 | + " public static void tearDownClass() {\n"
93 | + " driver.quit();\n"
94 | + " }\n\n"
95 | + " public static void switchWin(WebDriver driver, String title) {\n"
96 | + " String target = driver.getWindowHandle();\n"
97 | + " for (String handle : driver.getWindowHandles()) {\n"
98 | + " driver.switchTo().window(handle);\n"
99 | + " if (driver.getTitle().equals(title)) {\n"
100 | + " target = handle;\n"
101 | + " }\n"
102 | + " }\n"
103 | + " driver.switchTo().window(target);\n"
104 | + " }\n"
105 | + "}\n");
106 | footer = 18; //lines from the insert point to the bottom
107 | }
108 |
109 | @Override
110 | void writeStart() {
111 | n++;
112 | ui.insertCode("\n @Test\n"
113 | + " public void test" + n + "() {", footer);
114 | }
115 |
116 | @Override
117 | void writeEnd() {
118 | ui.insertCode("\n }\n", footer);
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/main/java/objectivetester/Test5Writer.java:
--------------------------------------------------------------------------------
1 | package objectivetester;
2 |
3 | /**
4 | *
5 | * @author Steve
6 | */
7 | class Test5Writer extends DefaultWriter {
8 | //browsermodel calls this and it updates the generated code
9 | //creates numbered junit5 test cases
10 |
11 | private int n;
12 |
13 | Test5Writer(UserInterface ui) {
14 | this.n = 0;
15 | this.ui = ui;
16 | }
17 |
18 | @Override
19 | void writeHeader(String url, String browser) {
20 | String driverImport = "";
21 | String sysProp = "";
22 | String driverInit = "";
23 |
24 | switch (browser) {
25 |
26 | case "FF":
27 | driverImport = "import org.openqa.selenium.firefox.FirefoxDriver;\n";
28 | if (System.getProperty("webdriver.gecko.driver") != null) {
29 | sysProp = " System.setProperty(\"webdriver.gecko.driver\", \"" + System.getProperty("webdriver.gecko.driver") + "\");\n";
30 | }
31 | driverInit = " driver = new FirefoxDriver();\n";
32 | break;
33 |
34 | case "CR":
35 | driverImport = "import org.openqa.selenium.chrome.ChromeDriver;\n";
36 | if (System.getProperty("webdriver.chrome.driver") != null) {
37 | sysProp = " System.setProperty(\"webdriver.chrome.driver\", \"" + System.getProperty("webdriver.chrome.driver") + "\");\n";
38 | }
39 | driverInit = " driver = new ChromeDriver();\n";
40 | break;
41 |
42 | case "ED":
43 | driverImport = "import org.openqa.selenium.edge.EdgeDriver;\n";
44 | if (System.getProperty("webdriver.edge.driver") != null) {
45 | sysProp = " System.setProperty(\"webdriver.edge.driver\", \"" + System.getProperty("webdriver.edge.driver") + "\");\n";
46 | }
47 | driverInit = " WebDriver driver = new EdgeDriver();\n";
48 | break;
49 |
50 | case "SA":
51 | driverImport = "import org.openqa.selenium.safari.SafariDriver;\n";
52 | driverInit = " driver = new SafariDriver();\n";
53 | break;
54 | }
55 |
56 | ui.addCode("import java.time.Duration;\n"
57 | + driverImport
58 | + "import org.openqa.selenium.JavascriptExecutor;\n"
59 | + "import org.openqa.selenium.WebDriver;\n"
60 | + "import org.openqa.selenium.WebElement;\n"
61 | + "import org.openqa.selenium.By;\n"
62 | + "import org.openqa.selenium.Alert;\n"
63 | + "import org.openqa.selenium.support.ui.Select;\n"
64 | + "import org.junit.jupiter.api.AfterAll;\n"
65 | + "import org.junit.jupiter.api.AfterEach;\n"
66 | + "import org.junit.jupiter.api.BeforeAll;\n"
67 | + "import org.junit.jupiter.api.BeforeEach;\n"
68 | + "import org.junit.jupiter.api.Test;\n"
69 | + "import static org.junit.jupiter.api.Assertions.*;\n"
70 | + "import org.junit.jupiter.api.TestMethodOrder;\n"
71 | + "import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;\n"
72 | + "import org.junit.jupiter.api.Order;\n\n"
73 | + "@TestMethodOrder(OrderAnnotation.class)\n"
74 | + "public class RecordedTest {\n\n"
75 | + " public RecordedTest() {\n"
76 | + " }\n"
77 | + " WebElement element;\n"
78 | + " Alert alert;\n"
79 | + " Select selector;\n"
80 | + " static WebDriver driver;\n"
81 | + " static JavascriptExecutor js;\n\n"
82 | + " @BeforeAll\n"
83 | + " public static void setUp() {\n"
84 | + sysProp
85 | + driverInit
86 | + " js = (JavascriptExecutor) driver;\n"
87 | + " driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));\n"
88 | + " driver.manage().timeouts().scriptTimeout(Duration.ofSeconds(10));\n"
89 | + " driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));\n"
90 | + " driver.get(\"" + url + "\");\n"
91 | + " }\n\n"
92 | + " @AfterAll\n"
93 | + " public static void tearDown() {\n"
94 | + " driver.quit();\n"
95 | + " }\n\n"
96 | + " public static void switchWin(WebDriver driver, String title) {\n"
97 | + " String target = driver.getWindowHandle();\n"
98 | + " for (String handle : driver.getWindowHandles()) {\n"
99 | + " driver.switchTo().window(handle);\n"
100 | + " if (driver.getTitle().equals(title)) {\n"
101 | + " target = handle;\n"
102 | + " }\n"
103 | + " }\n"
104 | + " driver.switchTo().window(target);\n"
105 | + " }\n"
106 | + "}\n");
107 | footer = 18; //lines from the insert point to the bottom
108 | }
109 |
110 | @Override
111 | void writeStart() {
112 | n++;
113 | ui.insertCode("\n @Test\n"
114 | + " @Order(" + n + ")\n"
115 | + " public void test" + n + "() {", footer);
116 | }
117 |
118 | @Override
119 | void writeEnd() {
120 | ui.insertCode("\n }\n", footer);
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/main/java/objectivetester/ScriptWriter.java:
--------------------------------------------------------------------------------
1 | package objectivetester;
2 |
3 | /**
4 | *
5 | * @author Steve
6 | */
7 | class ScriptWriter extends DefaultWriter {
8 | //browsermodel calls this and it updates the generated code
9 | //creates a java program - e.g. for task automation
10 |
11 | ScriptWriter(UserInterface ui) {
12 | this.ui = ui;
13 | }
14 |
15 | @Override
16 | void writeHeader(String url, String browser) {
17 | String driverImport = "";
18 | String sysProp = "";
19 | String driverInit = "";
20 |
21 | switch (browser) {
22 |
23 | case "FF":
24 | driverImport = "import org.openqa.selenium.firefox.FirefoxDriver;\n";
25 | if (System.getProperty("webdriver.gecko.driver") != null) {
26 | sysProp = " System.setProperty(\"webdriver.gecko.driver\", \""+System.getProperty("webdriver.gecko.driver")+"\");\n";
27 | }
28 | driverInit = " WebDriver driver = new FirefoxDriver();\n";
29 | break;
30 |
31 | case "CR":
32 | driverImport = "import org.openqa.selenium.chrome.ChromeDriver;\n";
33 | if (System.getProperty("webdriver.chrome.driver") != null) {
34 | sysProp = " System.setProperty(\"webdriver.chrome.driver\", \""+System.getProperty("webdriver.chrome.driver")+"\");\n";
35 | }
36 | driverInit = " WebDriver driver = new ChromeDriver();\n";
37 | break;
38 |
39 | case "ED":
40 | driverImport = "import org.openqa.selenium.edge.EdgeDriver;\n";
41 | if (System.getProperty("webdriver.edge.driver") != null) {
42 | sysProp = " System.setProperty(\"webdriver.edge.driver\", \""+System.getProperty("webdriver.edge.driver")+"\");\n";
43 | }
44 | driverInit = " WebDriver driver = new EdgeDriver();\n";
45 | break;
46 |
47 | case "SA":
48 | driverImport = "import org.openqa.selenium.safari.SafariDriver;\n";
49 | driverInit = " WebDriver driver = new SafariDriver();\n";
50 | break;
51 | }
52 |
53 | ui.addCode("import java.time.Duration;\n"
54 | + driverImport
55 | + "import org.openqa.selenium.JavascriptExecutor;\n"
56 | + "import org.openqa.selenium.WebDriver;\n"
57 | + "import org.openqa.selenium.WebElement;\n"
58 | + "import org.openqa.selenium.By;\n"
59 | + "import org.openqa.selenium.Alert;\n"
60 | + "import org.openqa.selenium.support.ui.Select;\n\n"
61 | + "public class RecordedScript {\n\n"
62 | + " public static void main(String[] args) {\n"
63 | + " WebElement element;\n"
64 | + " Alert alert;\n"
65 | + " Select selector;\n"
66 | + sysProp
67 | + driverInit
68 | + " JavascriptExecutor js = (JavascriptExecutor) driver;\n"
69 | + " driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));\n"
70 | + " driver.manage().timeouts().scriptTimeout(Duration.ofSeconds(10));\n"
71 | + " driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));\n"
72 | + " driver.get(\"" + url + "\");\n\n\n"
73 | + " driver.quit();\n"
74 | + " }\n"
75 | + " public static void switchWin(WebDriver driver, String title) {\n"
76 | + " String target = driver.getWindowHandle();\n"
77 | + " for (String handle : driver.getWindowHandles()) {\n"
78 | + " driver.switchTo().window(handle);\n"
79 | + " if (driver.getTitle().equals(title)) {\n"
80 | + " target = handle;\n"
81 | + " }\n"
82 | + " }\n"
83 | + " driver.switchTo().window(target);\n"
84 | + " }\n"
85 | + "}\n");
86 | footer = 16; //lines from the insert point to the bottom
87 | }
88 |
89 | @Override
90 | void writeVerifyElement(String value, String method) {
91 | String check = ".contentEquals(\"" + value + "\")";
92 | if (value == null) {
93 | check = " == null";
94 | } else {
95 |
96 | }
97 | ui.insertCode("\n //verify:" + value + "\n"
98 | + " if (element.getAttribute(\"" + method + "\")" + check + ") {\n"
99 | + " System.out.println(\"" + method + " = " + value + "\");\n"
100 | + " }"
101 | + "", footer);
102 | }
103 |
104 | @Override
105 | void writeVerifyPage(String value) {
106 | if (value != null) {
107 | value = "\"" + value + "\"";
108 | }
109 | ui.insertCode("\n //verify:" + value + "\n"
110 | + " if (driver.getTitle().contentEquals(" + value + ")) {\n"
111 | + " System.out.println(\"title= \" +" + value + ");\n"
112 | + " }"
113 | + "", footer);
114 | }
115 |
116 | @Override
117 | void writeVerifyCookie(String name, String value) {
118 | ui.insertCode("\n //verify:" + value + "\n"
119 | + " if (driver.manage().getCookieNamed(\"" + name + "\").getValue().contentEquals(\"" + value + "\")) {\n"
120 | + " System.out.println(\"" + name + " = " + value + "\");\n"
121 | + " }"
122 | + "", footer);
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/main/java/objectivetester/JsWriter.java:
--------------------------------------------------------------------------------
1 | package objectivetester;
2 |
3 | /**
4 | *
5 | * @author Steve
6 | */
7 | class JsWriter extends DefaultWriter {
8 | //browsermodel calls this and it updates the generated code
9 | //Webdriver.io v7
10 |
11 | private int n = 0;
12 |
13 | JsWriter(UserInterface ui) {
14 | this.n = 0;
15 | this.ui = ui;
16 | }
17 |
18 | @Override
19 | void writeHeader(String url, String browser) {
20 | ui.addCode("describe('webdriver.io v7 test suite', () => {\n\n"
21 | + " before(async () => {\n"
22 | + " browser.setTimeout(\n"
23 | + " { 'implicit': 60000 },\n"
24 | + " { 'pageLoad': 60000 },\n"
25 | + " { 'script': 60000 })\n"
26 | + " await browser.url('" + url + "')\n"
27 | + " })\n\n"
28 | + " after(async () => {\n"
29 | + " })\n\n"
30 | + "})\n");
31 | footer = 3; //lines from the insert point to the bottom
32 |
33 | }
34 |
35 | @Override
36 | void writeFindEvent(String method, String attribute) {
37 | ui.insertCode("\n //find:" + attribute + "\n"
38 | + " const element = await $('" + wdioMethod(method, attribute) + "')"
39 | + "", footer);
40 | }
41 |
42 | @Override
43 | void writeClickEvent(String method, String attribute) {
44 | ui.insertCode("\n //click:" + attribute + "\n"
45 | + " await (await $('" + wdioMethod(method, attribute) + "')).click()"
46 | + "", footer);
47 | }
48 |
49 | @Override
50 | void writeInputEvent(String data) {
51 | ui.insertCode("\n element.setValue('" + data + "')"
52 | + "", footer);
53 | }
54 |
55 | @Override
56 | void writeSelectEvent(String data) {
57 | ui.insertCode("\n element.selectByVisibleText(\"" + data + "\")"
58 | + "", footer);
59 | }
60 |
61 | @Override
62 | void writeInputjsEvent(String jsInput) {
63 | ui.insertCode("\n browser.execute(\"" + jsInput + "\")"
64 | + "", footer);
65 | }
66 |
67 | @Override
68 | void writeAlertClick(String question, boolean choice) {
69 | String action;
70 | if (choice) {
71 | action = " browser.acceptAlert()\n";
72 | } else {
73 | action = " browser.dismissAlert()\n";
74 | }
75 | ui.insertCode("\n //alert:" + question + "\n"
76 | + action
77 | + "", footer);
78 | }
79 |
80 | @Override
81 | void writeSwitchByIndex(int frame) {
82 | ui.insertCode("\n //switch to:" + frame + "\n"
83 | + " await browser.switchToFrame(" + frame + ")"
84 | + "", footer);
85 | }
86 |
87 | @Override
88 | void writeSwitchBack() {
89 | ui.insertCode("\n //switch back\n"
90 | + " await browser.switchToParentFrame()"
91 | + "", footer);
92 | }
93 |
94 | @Override
95 | void writeSwitchWin(String title) {
96 | ui.insertCode("\n //switch to:" + title + "\n"
97 | + " await browser.switchWindow('" + title + "')"
98 | + "", footer);
99 | }
100 |
101 | @Override
102 | void writeVerifyElement(String value, String method) {
103 | if (value != null) {
104 | value = "'" + value + "'";
105 | }
106 | String line;
107 | switch (method) {
108 | case "checked":
109 | if (value == null) {
110 | line = " await expect(element).not.toBeChecked()";
111 | } else {
112 | line = " await expect(element).toBeChecked()";
113 | }
114 | break;
115 | case "value":
116 | line = " await expect(element).toHaveValue(" + value + ")";
117 | break;
118 | case "href":
119 | line = " await expect(element).toHaveHref(" + value + ")";
120 | break;
121 | case "gettext":
122 | line = " await expect(element).toHaveText([" + value + "])";
123 | break;
124 | default:
125 | line = " await expect(element).toHaveAttr('" + method + "', " + value + ")";
126 | }
127 | ui.insertCode("\n //assert:" + value + "\n"
128 | + line
129 | + "", footer);
130 | }
131 |
132 | @Override
133 | void writeVerifyPage(String value) {
134 | if (value != null) {
135 | value = "'" + value + "'";
136 | }
137 | ui.insertCode("\n //assert:" + value + "\n"
138 | + " await expect(browser).toHaveTitle(" + value + ")"
139 | + "", footer);
140 | }
141 |
142 | @Override
143 | void writeVerifyCookie(String name, String value) {
144 | ui.insertCode("\n //assert:" + value + "\n"
145 | + " expect(browser.getCookies(['" + name + "'])).toHaveValue('" + value.replaceAll("\"", "'") + "')"
146 | + "", footer);
147 | }
148 |
149 | @Override
150 | void comment(String text) {
151 | ui.insertCode("\n //" + text + "\n", footer);
152 | }
153 |
154 | @Override
155 | void writeStart() {
156 | n++;
157 | ui.insertCode("\n it('test " + n + "', async () => {", footer);
158 | }
159 |
160 | @Override
161 | void writeEnd() {
162 | ui.insertCode("\n })\n", footer);
163 | }
164 |
165 | String wdioMethod(String method, String attribute) {
166 | switch (method) {
167 | case "linkText":
168 | return "=" + attribute;
169 | case "name":
170 | return "[name=\"" + attribute + "\"]";
171 | case "id":
172 | return "#" + attribute;
173 | case "cssSelector":
174 | return attribute.replaceAll("'", "\"");
175 | case "className":
176 | return "." + attribute;
177 | default:
178 | return attribute;
179 | }
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/src/main/java/objectivetester/EventListener.java:
--------------------------------------------------------------------------------
1 | package objectivetester;
2 |
3 | import java.awt.event.ActionEvent;
4 | import java.awt.event.MouseAdapter;
5 | import java.awt.event.MouseEvent;
6 | import java.util.ArrayList;
7 | import javax.swing.JPopupMenu;
8 | import javax.swing.JTable;
9 | import org.openqa.selenium.WebElement;
10 |
11 | /**
12 | *
13 | * @author Steve
14 | */
15 | class EventListener extends MouseAdapter implements java.awt.event.ActionListener {
16 |
17 | JPopupMenu popup;
18 | JTable table;
19 | BrowserDriver bd;
20 | int current;
21 |
22 | EventListener(JPopupMenu popup, JTable table, BrowserDriver bd) {
23 | this.popup = popup;
24 | this.table = table;
25 | this.bd = bd;
26 | }
27 |
28 | @Override
29 | public void mouseClicked(MouseEvent e) {
30 | }
31 |
32 | @Override
33 | public void mousePressed(MouseEvent e) {
34 | if (bd.safe) {
35 | //dont allow unsafe interactions until the examiner has finished
36 | clickEvent(e);
37 | popupEvent(e);
38 | }
39 | }
40 |
41 | @Override
42 | public void mouseReleased(MouseEvent e) {
43 | if (bd.safe) {
44 | //dont allow unsafe interactions until the examiner has finished
45 | popupEvent(e);
46 | }
47 | }
48 |
49 | private void popupEvent(MouseEvent e) {
50 | if (e.isPopupTrigger()) {
51 | //reenable all choices
52 | popup.getComponent(Const.POP_CLICK).setEnabled(true); //click
53 | popup.getComponent(Const.POP_FIND).setEnabled(true); //find
54 | popup.getComponent(Const.POP_ASSERT).setEnabled(true); //assert
55 | popup.getComponent(Const.POP_ID).setEnabled(true); //identify
56 |
57 | int idx = table.rowAtPoint(e.getPoint());
58 | table.getSelectionModel().setSelectionInterval(idx, idx);
59 | current = table.getSelectedRow();
60 |
61 | //disable the invalid choices
62 | if ((table.getValueAt(current, Const.TAB_ELEMENT).toString().contentEquals(Const.TITLE))) {
63 | //cant elementFind or ident a page, so grey it out
64 | popup.getComponent(Const.POP_FIND).setEnabled(false);
65 | popup.getComponent(Const.POP_ID).setEnabled(false);
66 | if (!(table.getValueAt(current, Const.TAB_LOCATION).toString().contentEquals(Const.CURRENT))) {
67 | //cant assert other pages
68 | popup.getComponent(Const.POP_ASSERT).setEnabled(false);
69 | } else {
70 | //cant click on current page
71 | popup.getComponent(Const.POP_CLICK).setEnabled(false);
72 | }
73 | }
74 | if (table.getValueAt(current, Const.TAB_ELEMENT).toString().contentEquals(Const.COOKIE)) {
75 | //can only assert and change a cookie
76 | popup.getComponent(Const.POP_CLICK).setEnabled(false);
77 | popup.getComponent(Const.POP_ID).setEnabled(false);
78 | popup.getComponent(Const.POP_FIND).setEnabled(false);
79 | }
80 | if (table.getValueAt(current, Const.TAB_ELEMENT).toString().contentEquals("form") && !table.getValueAt(current, Const.TAB_ELEMENT).toString().contains(":")) {
81 | //can only assert form elements, not forms
82 | popup.getComponent(Const.POP_CLICK).setEnabled(false);
83 | popup.getComponent(Const.POP_ASSERT).setEnabled(false);
84 | }
85 | if (table.getValueAt(current, Const.TAB_ELEMENT).toString().endsWith(":hidden")) {
86 | //cant click or id hidden form fields
87 | popup.getComponent(Const.POP_CLICK).setEnabled(false);
88 | popup.getComponent(Const.POP_ID).setEnabled(false);
89 | }
90 | if (table.getValueAt(current, Const.TAB_ELEMENT).toString().startsWith(Const.INVISIBLE)) {
91 | //cant click or id invisible objects
92 | popup.getComponent(Const.POP_CLICK).setEnabled(false);
93 | popup.getComponent(Const.POP_ID).setEnabled(false);
94 | }
95 | //show the popup menu
96 | popup.show(e.getComponent(), e.getX(), e.getY());
97 | }
98 | }
99 |
100 | private void clickEvent(MouseEvent e) {
101 | int idx = table.rowAtPoint(e.getPoint());
102 | table.getSelectionModel().setSelectionInterval(idx, idx);
103 | current = table.getSelectedRow();
104 | Object stack;
105 | String element = table.getModel().getValueAt(current, Const.TAB_ELEMENT).toString();
106 | if (table.getModel().getValueAt(current, Const.TAB_LOCATION).getClass().equals(String.class)) {
107 | stack = (String) table.getModel().getValueAt(current, Const.TAB_LOCATION);
108 | } else {
109 | stack = (ArrayList) table.getModel().getValueAt(current, Const.TAB_LOCATION);
110 | }
111 | Object webElement = table.getModel().getValueAt(current, Const.TAB_WEBELEMENT);
112 | //if it's an element, highlight it
113 | //the element column is only in the model, so use the model to retreive it
114 | if (!element.contentEquals(Const.TITLE) && !element.startsWith(Const.INVISIBLE) && !element.contentEquals(Const.COOKIE)) {
115 | bd.highlight((WebElement) webElement, stack);
116 | }
117 | }
118 |
119 | @Override
120 | public void actionPerformed(ActionEvent e) {
121 | String element = table.getModel().getValueAt(current, Const.TAB_ELEMENT).toString();
122 | Object stack;
123 | if (table.getModel().getValueAt(current, Const.TAB_LOCATION).getClass().equals(String.class)) {
124 | stack = (String) table.getModel().getValueAt(current, Const.TAB_LOCATION);
125 | } else {
126 | stack = (ArrayList) table.getModel().getValueAt(current, Const.TAB_LOCATION);
127 | }
128 | String name = table.getModel().getValueAt(current, Const.TAB_NAME).toString();
129 | String id = table.getModel().getValueAt(current, Const.TAB_ID).toString();
130 | Object value = table.getModel().getValueAt(current, Const.TAB_VALUE);
131 | Object webElement = table.getModel().getValueAt(current, Const.TAB_WEBELEMENT);
132 | //clicking on an element
133 | if (e.getActionCommand().contentEquals(Const.CLICK)) {
134 | if (element.contains("date") || element.contains("datetime-local") || element.contains("email") || element.contains("file") || element.contains("month") || element.contains("number") || element.contains("password") || element.contains("search") || element.contains("tel") || element.contains("text") || element.contains("time") || element.contains("url") || element.contains("week")) {
135 | //input element
136 | bd.input((WebElement) webElement, stack);
137 | } else if (element.endsWith(":select-one")) {
138 | //selection
139 | bd.select((WebElement) webElement, stack);
140 | } else if (element.contentEquals(Const.TITLE)) {
141 | //page title
142 | bd.switchWin((String) webElement, (String) value);
143 | } else if (element.endsWith(":range") || element.endsWith(":color")) {
144 | //special input
145 | bd.inputjs((WebElement) webElement, stack);
146 | } else {
147 | //clickable
148 | bd.click((WebElement) webElement, stack);
149 | }
150 | }
151 |
152 | //finding an element
153 | if (e.getActionCommand()
154 | .contentEquals(Const.FIND)) {
155 | if (element.contentEquals(Const.TITLE)) {
156 | //page title
157 | } else {
158 | //page element
159 | bd.find((WebElement) webElement, stack, Const.FIND);
160 | }
161 | }
162 |
163 | //asserting the value of an element
164 | if (e.getActionCommand()
165 | .contentEquals(Const.ASSERT)) {
166 | if (element.contentEquals(Const.TITLE)) {
167 | //page title
168 | bd.verifyPage((String) value);
169 | } else if (element.contentEquals(Const.COOKIE)) {
170 | bd.verifyCookie((String) name, (String) value);
171 | } else {
172 | //page element
173 | bd.verify((WebElement) webElement, stack, element, (String) value);
174 | }
175 | }
176 |
177 | //identifying an element
178 | if (e.getActionCommand()
179 | .contentEquals(Const.IDENTIFY)) {
180 | if (element.contentEquals(Const.TITLE)) {
181 | //page title
182 | } else {
183 | //page element
184 | bd.ident((WebElement) webElement, stack, (String) element, name, id, (String) value);
185 |
186 | }
187 | }
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/src/main/java/objectivetester/BrowserDriver.java:
--------------------------------------------------------------------------------
1 | package objectivetester;
2 |
3 | /**
4 | *
5 | * @author Steve
6 | */
7 | import java.time.Duration;
8 | import java.util.ArrayList;
9 | import java.util.Arrays;
10 | import java.util.List;
11 | import java.util.Set;
12 | import org.openqa.selenium.Alert;
13 | import org.openqa.selenium.By;
14 | import org.openqa.selenium.Cookie;
15 | import org.openqa.selenium.ElementNotInteractableException;
16 | import org.openqa.selenium.InvalidArgumentException;
17 | import org.openqa.selenium.InvalidSelectorException;
18 | import org.openqa.selenium.JavascriptExecutor;
19 | import org.openqa.selenium.NoAlertPresentException;
20 | import org.openqa.selenium.NoSuchFrameException;
21 | import org.openqa.selenium.SessionNotCreatedException;
22 | import org.openqa.selenium.StaleElementReferenceException;
23 | import org.openqa.selenium.TimeoutException;
24 | import org.openqa.selenium.WebDriver;
25 | import org.openqa.selenium.WebDriverException;
26 | import org.openqa.selenium.WebElement;
27 | import org.openqa.selenium.chrome.ChromeDriver;
28 | import org.openqa.selenium.edge.EdgeDriver;
29 | import org.openqa.selenium.firefox.FirefoxDriver;
30 | import org.openqa.selenium.remote.NoSuchDriverException;
31 | import org.openqa.selenium.safari.SafariDriver;
32 | import org.openqa.selenium.support.ui.*;
33 |
34 | class BrowserDriver implements Runnable {
35 |
36 | WebDriver driver;
37 | JavascriptExecutor js;
38 | UserInterface ui;
39 | DefaultWriter writer;
40 | boolean safe = false;
41 | ArrayList CSSselectors;
42 | ArrayList allElements;
43 |
44 | BrowserDriver(UserInterface ui) {
45 | this.ui = ui;
46 | }
47 |
48 | void initWriter(String selected) {
49 | switch (selected) {
50 | case "junit":
51 | writer = new TestWriter(ui);
52 | break;
53 | case "junit5":
54 | writer = new Test5Writer(ui);
55 | break;
56 | case "js":
57 | writer = new JsWriter(ui);
58 | break;
59 | default:
60 | writer = new ScriptWriter(ui);
61 | break;
62 | }
63 | }
64 |
65 | boolean initFF(String url, String path) {
66 | //FF
67 | try {
68 | if (!path.isEmpty()) {
69 | System.setProperty("webdriver.gecko.driver", path);
70 | }
71 | driver = new FirefoxDriver();
72 | js = (JavascriptExecutor) driver;
73 | writer.writeHeader(url, "FF");
74 | driver.get(url);
75 | } catch (NoSuchDriverException nde) {
76 | System.err.println(nde);
77 | ui.errorMessage("Path to Gecko driver is invalid, check settings.");
78 | return false;
79 | } catch (InvalidArgumentException iae) {
80 | System.err.println(iae);
81 | ui.errorMessage("Invalid URL?");
82 | return false;
83 | } catch (Exception e) {
84 | System.err.println(e);
85 | return false;
86 | }
87 | return true;
88 | }
89 |
90 | boolean initCR(String url, String path) {
91 | //Chrome
92 | try {
93 | if (!path.isEmpty()) {
94 | System.setProperty("webdriver.chrome.driver", path);
95 | }
96 | driver = new ChromeDriver();
97 | js = (JavascriptExecutor) driver;
98 | writer.writeHeader(url, "CR");
99 | driver.get(url);
100 | } catch (NoSuchDriverException nde) {
101 | System.err.println(nde);
102 | ui.errorMessage("Path to Chrome driver is invalid, check settings.");
103 | return false;
104 | } catch (InvalidArgumentException iae) {
105 | System.err.println(iae);
106 | ui.errorMessage("Invalid URL?");
107 | return false;
108 | } catch (Exception e) {
109 | System.err.println(e);
110 | return false;
111 | }
112 | return true;
113 | }
114 |
115 | boolean initED(String url, String path) {
116 | //Edge
117 | try {
118 | if (!path.isEmpty()) {
119 | System.setProperty("webdriver.edge.driver", path);
120 | }
121 | driver = new EdgeDriver();
122 | js = (JavascriptExecutor) driver;
123 | writer.writeHeader(url, "ED");
124 | driver.get(url);
125 | } catch (NoSuchDriverException nde) {
126 | System.err.println(nde);
127 | ui.errorMessage("Path to Edge driver is invalid, check settings.");
128 | return false;
129 | } catch (InvalidArgumentException iae) {
130 | ui.errorMessage("Invalid URL?");
131 | return false;
132 | } catch (Exception e) {
133 | System.err.println(e);
134 | return false;
135 | }
136 | return true;
137 | }
138 |
139 | boolean initSA(String url) {
140 | //Safari
141 | try {
142 | driver = new SafariDriver();
143 | js = (JavascriptExecutor) driver;
144 | writer.writeHeader(url, "SA");
145 | driver.get(url);
146 | } catch (SessionNotCreatedException e) {
147 | ui.errorMessage(e.getMessage().substring(0, e.getMessage().indexOf(10)));
148 | return false;
149 | } catch (Exception e) {
150 | System.err.println(e);
151 | return false;
152 | }
153 | return true;
154 | }
155 |
156 | @Override
157 | public void run() {
158 | if (driver != null) {
159 | safe = false;
160 |
161 | //get list of CSS selectors to search for
162 | String[] selectors = ui.getCSSselectors().split("\\s*,\\s*");
163 | CSSselectors = new ArrayList<>(Arrays.asList(selectors));
164 |
165 | //reset element list
166 | allElements = new ArrayList<>();
167 |
168 | driver.manage().timeouts().implicitlyWait(Duration.ofMillis(10));
169 | //examine the root contents
170 | examine(Const.PAGE);
171 | ui.finished();
172 | safe = true;
173 | }
174 | }
175 |
176 | void examine(Object stack) {
177 | try {
178 | String value;
179 | driver.switchTo().defaultContent();
180 |
181 | if ((stack.getClass().equals(String.class)) && ((String) stack).equals(Const.PAGE)) {
182 | String current = driver.getWindowHandle();
183 | //indicate current window
184 | ui.addItem(Const.TITLE, (Object) Const.CURRENT, "", "", driver.getTitle(), current, true);
185 | //show all available windows
186 | List winList = new ArrayList<>(driver.getWindowHandles());
187 | for (String handle : winList) {
188 | driver.switchTo().window(handle);
189 | if (!handle.contentEquals(current)) {
190 | ui.addItem(Const.TITLE, Const.WINDOW, "", "", driver.getTitle(), handle, true);
191 | }
192 | }
193 | driver.switchTo().window(current);
194 |
195 | //get cookies
196 | Set cookies = driver.manage().getCookies();
197 | for (Cookie c : cookies) {
198 | ui.addItem(Const.COOKIE, Const.BROWSER, c.getName(), c.getDomain() + c.getPath(), c.getValue(), null, true);
199 | }
200 |
201 | } else {
202 | //drill down the frames stack
203 | traverse((ArrayList) stack, false);
204 | }
205 |
206 | try {
207 | //links
208 | //System.out.println("links:" + Integer.parseInt((js.executeScript("return document.links.length;")).toString()));
209 | List links = (List) (js.executeScript("return document.links;"));
210 | for (WebElement element : links) {
211 | ui.addItem("link", stack, element.getAttribute("text").trim(), element.getAttribute("id"), element.getAttribute("href"), element, element.isDisplayed());
212 | allElements.add(element);
213 | }
214 | } catch (Exception e) {
215 | //ui.errorMessage("Failed to find links");
216 | }
217 |
218 | try {
219 | //forms
220 | //System.out.println("forms:" + Integer.parseInt((js.executeScript("return document.forms.length;")).toString()));
221 | //you can't return all the forms, so do each individually
222 | int i = 0;
223 | WebElement form = (WebElement) ((js.executeScript("return document.forms[" + i + "];")));
224 | while (form != null) {
225 | ui.addItem("form" + i, stack, form.getAttribute("name"), form.getAttribute("id"), "", form, form.isDisplayed());
226 | allElements.add(form);
227 | //System.out.println("form " + i + ", " + Integer.parseInt((js.executeScript("return document.forms[" + i + "].length;")).toString()) + " elements");
228 |
229 | List formElement = (List) (js.executeScript("return document.forms[" + i + "].elements;"));
230 | for (WebElement element : formElement) {
231 | if ((element.getAttribute("type").contentEquals("radio")) || (element.getAttribute("type").contentEquals("checkbox"))) {
232 | value = element.getAttribute("checked");
233 | } else {
234 | value = element.getAttribute("value");
235 | }
236 |
237 | ui.addItem("form" + i + ":" + element.getAttribute("type"), stack, element.getAttribute("name"), element.getAttribute("id"), value, element, element.isDisplayed());
238 | allElements.add(element);
239 | }
240 | i++;
241 | form = (WebElement) ((js.executeScript("return document.forms[" + i + "];")));
242 | }
243 | } catch (Exception e) {
244 | //ui.errorMessage("Failed to find form content");
245 | }
246 |
247 | try {
248 | //non-form input elements
249 | List inputs = driver.findElements(By.tagName("input"));
250 | inputs.addAll(driver.findElements(By.tagName("select")));
251 | inputs.addAll(driver.findElements(By.tagName("button")));
252 |
253 | for (WebElement element : inputs) {
254 | //see if we've added this webElement already
255 | Boolean present = false;
256 | for (WebElement in : allElements) {
257 | if (in.equals(element)) {
258 | present = true;
259 | }
260 | }
261 | if (!present) {
262 | if ((element.getAttribute("type").contentEquals("radio")) || (element.getAttribute("type").contentEquals("checkbox"))) {
263 | value = element.getAttribute("checked");
264 | } else {
265 | value = element.getAttribute("value");
266 | }
267 | ui.addItem("input:" + element.getAttribute("type"), stack, element.getAttribute("name"), element.getAttribute("id"), value, element, element.isDisplayed());
268 | allElements.add(element);
269 | }
270 |
271 | }
272 | } catch (Exception e) {
273 | //ui.errorMessage("Failed to find input elements");
274 | }
275 |
276 | try {
277 | //images
278 | //System.out.println("images:" + Integer.parseInt((js.executeScript("return document.images.length;")).toString()));
279 | List images = (List) (js.executeScript("return document.images;"));
280 | for (WebElement element : images) {
281 | ui.addItem("image", stack, element.getAttribute("alt"), element.getAttribute("id"), element.getAttribute("src"), element, element.isDisplayed());
282 | allElements.add(element);
283 | }
284 | } catch (Exception e) {
285 | //ui.errorMessage("Failed to find images");
286 | }
287 |
288 | try {
289 | //anchors
290 | //System.out.println("anchors:" + Integer.parseInt((js.executeScript("return document.anchors.length;")).toString()));
291 | List anchors = (List) (js.executeScript("return document.anchors;"));
292 | for (WebElement element : anchors) {
293 | ui.addItem("anchor", stack, element.getAttribute("text"), element.getAttribute("id"), element.getAttribute("name"), element, element.isDisplayed());
294 | allElements.add(element);
295 | }
296 | } catch (Exception e) {
297 | //ui.errorMessage("Failed to find anchors");
298 | }
299 |
300 | //custom CSS selectors
301 | if (CSSselectors.get(0).length() != 0) {
302 | for (String item : CSSselectors) {
303 | try {
304 | List custom = (List) driver.findElements(By.cssSelector(item));
305 | for (WebElement element : custom) {
306 | String elementVal = element.getAttribute("value");
307 | if (elementVal == null) {
308 | elementVal = element.getText();
309 | }
310 | ui.addItem(element.getTagName().toLowerCase(), stack, element.getAttribute("id"), item, elementVal, element, element.isDisplayed());
311 | allElements.add(element);
312 | }
313 | } catch (Exception e) {
314 | //ui.errorMessage("Failed to find custom");
315 | }
316 | }
317 | }
318 |
319 | boolean validFrame = true;
320 | int frame = 0;
321 | while (validFrame) {
322 | try {
323 | driver.switchTo().frame(frame);
324 | } catch (NoSuchFrameException nse) {
325 | validFrame = false;
326 | }
327 |
328 | if (validFrame) {
329 | if (stack.getClass().equals(String.class)) {
330 | stack = new ArrayList<>();
331 | }
332 | driver.switchTo().parentFrame();
333 | ArrayList newstack = new ArrayList<>((ArrayList) stack);
334 | newstack.add(frame);
335 |
336 | //down the rabbit hole....
337 | examine(newstack);
338 |
339 | //restore original position
340 | driver.switchTo().parentFrame();
341 |
342 | frame++;
343 | }
344 | }
345 |
346 | } catch (TimeoutException | StaleElementReferenceException | ElementNotInteractableException e) {
347 | ui.rescan();
348 | } catch (WebDriverException e) {
349 | ui.abort();
350 | }
351 | }
352 |
353 | void close() {
354 | if (driver != null) {
355 | try {
356 | driver.quit();
357 | driver = null;
358 | } catch (WebDriverException e) {
359 | driver = null;
360 | }
361 | }
362 | }
363 |
364 | private void traverse(ArrayList stack, Boolean write) {
365 | for (int item = 0; item < stack.size(); item++) {
366 | int nextFrame = (int) stack.get(item);
367 | if (write) {
368 | writer.writeSwitchByIndex(nextFrame);
369 | }
370 | driver.switchTo().frame(nextFrame);
371 | }
372 | }
373 |
374 | void highlight(WebElement webElement, Object stack) {
375 | try {
376 | driver.switchTo().defaultContent();
377 | //drill down the frames
378 | if (stack.getClass().equals(ArrayList.class)) {
379 | traverse((ArrayList) stack, false);
380 | }
381 | js.executeScript("arguments[0].scrollIntoView(true);", webElement);
382 | String style = webElement.getAttribute("style");
383 | //System.out.println(webElement + style);
384 | js.executeScript("arguments[0].setAttribute('style', " + Const.HIGHLIGHT + ");", webElement);
385 | Thread.sleep(500);
386 | js.executeScript("arguments[0].setAttribute('style', 'arguments[1]');", webElement, style);
387 | } catch (TimeoutException | StaleElementReferenceException e) {
388 | ui.rescan();
389 | } catch (ElementNotInteractableException | InterruptedException e) {
390 | } catch (WebDriverException e) {
391 | ui.abort();
392 | }
393 | }
394 |
395 | RichElement elementFind(WebElement webElement, Object stack, String action) {
396 | driver.switchTo().defaultContent();
397 | //see if we can elementFind it first
398 | if (stack.getClass().equals(ArrayList.class)) {
399 | traverse((ArrayList) stack, false);
400 | }
401 | js.executeScript("arguments[0].scrollIntoView(true);", webElement);
402 | String name = webElement.getText();
403 | RichElement ele = elementFinder(webElement);
404 | driver.switchTo().defaultContent();
405 | if (ele.method != null) {
406 | //we can elementFind it, so write code to navigate
407 | if (stack.getClass().equals(ArrayList.class)) {
408 | //navigate to the webElement
409 | traverse((ArrayList) stack, true);
410 | }
411 | if (!action.equals(Const.CLICK)) {
412 | //write code to get the element
413 | writer.writeFindEvent(ele.method, ele.attribute);
414 | }
415 |
416 | //if we're just doing a elementFind, tidy up
417 | if (action.equals(Const.FIND)) {
418 | if (stack.getClass().equals(ArrayList.class)) {
419 | //if we had to navigate here, switch back
420 | writer.writeSwitchBack();
421 | }
422 |
423 | }
424 |
425 | } else {
426 | //failed to elementFind the webElement
427 |
428 | ui.errorMessage("Unable to uniquely identify " + name);
429 | writer.comment("Unable to uniquely identify " + name);
430 | }
431 | return ele;
432 | }
433 |
434 | void find(WebElement webElement, Object stack, String action) {
435 | writer.writeStart();
436 | elementFind(webElement, stack, action);
437 | writer.writeEnd();
438 | }
439 |
440 | void click(WebElement webElement, Object stack) {
441 | writer.writeStart();
442 | RichElement ele = elementFind(webElement, stack, Const.CLICK);
443 | if (ele.method != null) {
444 | writer.writeClickEvent(ele.method, ele.attribute);
445 | if (driver.getClass().getName().contains("SafariDriver")) {
446 | //workaround for a click problem with Safari that only happens in Wisard
447 | js.executeScript("arguments[0].click();", webElement);
448 | } else {
449 | webElement.click();
450 | }
451 |
452 | //if that caused an alert to popup, deal with it
453 | //prompting alerts are not dealt with yet, but are supported in webdriver
454 | //does anyone really use them?
455 | try {
456 | Alert alert = driver.switchTo().alert();
457 | if (alert != null) {
458 | String title = alert.getText();
459 | Boolean action = ui.alertResponse(title);
460 | if (action == false) {
461 | alert.dismiss();
462 | } else {
463 | alert.accept();
464 | }
465 | writer.writeAlertClick(title, action);
466 | ui.rescan();
467 | }
468 | } catch (NoAlertPresentException na) {
469 | //System.out.println("no alert");
470 | }
471 |
472 | if (stack.getClass().equals(ArrayList.class)) {
473 | //if we had to navigate here, switch back
474 | writer.writeSwitchBack();
475 | }
476 | driver.switchTo().defaultContent();
477 | }
478 | writer.writeEnd();
479 | }
480 |
481 | void input(WebElement webElement, Object stack) {
482 | String data = ui.enterValue(webElement.getAttribute("name"));
483 | if (data != null) {
484 | writer.writeStart();
485 | RichElement ele = elementFind(webElement, stack, "");
486 | if (ele.method != null) {
487 | writer.writeInputEvent(data);
488 | if (stack.getClass().equals(ArrayList.class)) {
489 | //if we had to navigate here, switch back
490 | writer.writeSwitchBack();
491 | }
492 | webElement.clear();
493 | webElement.sendKeys(data);
494 | driver.switchTo().defaultContent();
495 | }
496 | writer.writeEnd();
497 | }
498 | }
499 |
500 | void inputjs(WebElement webElement, Object stack) {
501 | String data = ui.enterValue(webElement.getAttribute("name"));
502 | if (data != null) {
503 | writer.writeStart();
504 | RichElement ele = elementFind(webElement, stack, "click");
505 | if (ele.method != null) {
506 |
507 | //this only works if the first match is the right element
508 | String jsInput = "javascript:var e=document.getElementsByName(\"" + ele.attribute + "\");e[0].value=\"" + data + "\";";
509 |
510 | if (ele.method.contentEquals("id")) {
511 | jsInput = "javascript:document.getElementById(\"" + ele.attribute + "\").value=\"" + data + "\";";
512 | }
513 | if (ele.method.contentEquals("cssSelector")) {
514 | jsInput = jsInput.replace("getElementsByName", "querySelectorAll");
515 | }
516 | if (ele.method.contentEquals("className")) {
517 | jsInput = jsInput.replace("getElementsByName", "getElementsByClassName");
518 | }
519 | writer.writeInputjsEvent(jsInput.replace("\"", "\\\""));
520 | if (stack.getClass().equals(ArrayList.class)) {
521 | //if we had to navigate here, switch back
522 | writer.writeSwitchBack();
523 | }
524 | js.executeScript(jsInput);
525 | driver.switchTo().defaultContent();
526 | }
527 | writer.writeEnd();
528 | }
529 | }
530 |
531 | void select(WebElement webElement, Object stack) {
532 | //extract the choices
533 | Select selector = new Select(webElement);
534 | List selectOptions = selector.getOptions();
535 | List items = new ArrayList<>();
536 | for (WebElement option : selectOptions) {
537 | items.add(option.getText());
538 | }
539 | String[] choices = items.toArray(new String[0]);
540 | //make a choice
541 | String data = ui.enterSelection(webElement.getAttribute("name"), choices);
542 | if (data != null) {
543 | writer.writeStart();
544 | RichElement ele = elementFind(webElement, stack, "");
545 | if (ele.method != null) {
546 | writer.writeSelectEvent(data);
547 | if (stack.getClass().equals(ArrayList.class)) {
548 | //if we had to navigate here, switch back
549 | writer.writeSwitchBack();
550 | }
551 | selector.selectByVisibleText(data);
552 | driver.switchTo().defaultContent();
553 | writer.writeEnd();
554 | }
555 | }
556 |
557 | }
558 |
559 | void verify(WebElement webElement, Object stack, String element, String expected) {
560 | writer.writeStart();
561 | RichElement ele = elementFind(webElement, stack, "");
562 | if (ele.method != null) {
563 | String verifymethod;
564 | if (element.contains("link")) {
565 | verifymethod = "href";
566 | } else if (element.contains("image")) {
567 | verifymethod = "src";
568 | } else if (element.contains("anchor")) {
569 | verifymethod = "name";
570 | } else if (element.contains("radio") || element.contains("checkbox")) {
571 | verifymethod = "checked";
572 | } else if (webElement.getAttribute("value") == null) {
573 | verifymethod = "gettext";
574 | } else {
575 | verifymethod = "value";
576 | }
577 |
578 | //System.out.println("expected:" + expected);
579 | //System.out.println("actual:" + webElement.getAttribute(verifymethod));
580 | //System.out.println("using:" + verifymethod);
581 | writer.writeVerifyElement(expected, verifymethod);
582 |
583 | if (stack.getClass().equals(ArrayList.class)) {
584 | //if we had to navigate here, switch back
585 | writer.writeSwitchBack();
586 | }
587 | }
588 | writer.writeEnd();
589 | }
590 |
591 | void verifyPage(String expected) {
592 | writer.writeStart();
593 | writer.writeVerifyPage(expected);
594 | writer.writeEnd();
595 | }
596 |
597 | void verifyCookie(String name, String expected) {
598 | writer.writeStart();
599 | writer.writeVerifyCookie(name, expected);
600 | writer.writeEnd();
601 | }
602 |
603 | void ident(WebElement webElement, Object stack, String element, String name, String id, String value) {
604 | driver.switchTo().defaultContent();
605 | if (stack.getClass().equals(ArrayList.class)) {
606 | traverse((ArrayList) stack, false);
607 | }
608 |
609 | RichElement ele = elementFinder(webElement);
610 | String method = "not found!";
611 | if (ele.method != null) {
612 | method = "By." + ele.method + "(\"" + ele.attribute + "\")";
613 | }
614 |
615 | String message = "Element: " + element
616 | + "
Name: " + name
617 | + "
ID: " + id
618 | + "
Value: " + value
619 | + "
Location: " + stack.toString()
620 | + "
Find Method: " + method
621 | + "
Outer HTML:"
622 | + "
" + webElement.getAttribute("outerHTML");
623 |
624 | try {
625 | String style = webElement.getAttribute("style");
626 | //System.out.println(webElement + style);
627 | js.executeScript("arguments[0].setAttribute('style', " + Const.HIGHLIGHT + ");", webElement);
628 | //highlight until the message box is cleared
629 | ui.elementIdent(message);
630 |
631 | js.executeScript("arguments[0].setAttribute('style', 'arguments[1]');", webElement, style);
632 | driver.switchTo().defaultContent();
633 | } catch (TimeoutException | StaleElementReferenceException e) {
634 | ui.rescan();
635 | } catch (ElementNotInteractableException e) {
636 | } catch (WebDriverException e) {
637 | ui.abort();
638 | }
639 |
640 | }
641 |
642 | void switchWin(String handle, String title) {
643 | try {
644 | writer.writeStart();
645 | writer.writeSwitchWin(title);
646 | writer.writeEnd();
647 | driver.switchTo().window(handle);
648 | } catch (TimeoutException | StaleElementReferenceException | ElementNotInteractableException e) {
649 | //do nothing, we're rescanning anyway
650 | } catch (WebDriverException e) {
651 | ui.abort();
652 | }
653 | ui.rescan();
654 | }
655 |
656 | private RichElement elementFinder(WebElement webElement) {
657 | //uniquely elementFind the webElement by the most descriptive attribute
658 | //
659 | //By.id
660 | //By.name
661 | //By.linkText
662 | //By.cssSelector - alt
663 | //By.cssSelector - href
664 | //By.cssSelector - src
665 | //By.cssSelector - title
666 | //By.className
667 | //By.cssSelector - class
668 | //By.cssSelector - type
669 | //By.cssSelector - value
670 | //By.cssSelector - custom
671 | List elements;
672 | String selector;
673 |
674 | //id
675 | if (!webElement.getAttribute("id").isEmpty()) { //prevent FF crash
676 | elements = driver.findElements(By.id(webElement.getAttribute("id")));
677 | if ((elements.size() == 1) && elements.contains(webElement)) {
678 | //System.out.println("found id:" + elements.get(0).getAttribute("id"));
679 | return new RichElement("id", elements.get(0).getAttribute("id"));
680 | }
681 | }
682 |
683 | //name
684 | if (webElement.getAttribute("name") != null) {
685 | elements = driver.findElements(By.name(webElement.getAttribute("name")));
686 | if ((elements.size() == 1) && elements.contains(webElement)) {
687 | //System.out.println("found frames:" + elements.get(0).getAttribute("frames"));
688 | return new RichElement("name", elements.get(0).getAttribute("name"));
689 | }
690 | }
691 |
692 | //linktext
693 | if (webElement.getText() != null) {
694 | elements = driver.findElements(By.linkText(webElement.getText()));
695 | if ((elements.size() == 1) && elements.contains(webElement)) {
696 | //System.out.println("found linktext:" + elements.get(0).getText());
697 | return new RichElement("linkText", elements.get(0).getText());
698 | }
699 | }
700 |
701 | //alt
702 | try {
703 | selector = "[alt='" + webElement.getAttribute("alt") + "']";
704 | elements = driver.findElements(By.cssSelector(selector));
705 | if ((elements.size() == 1) && elements.contains(webElement)) {
706 | //System.out.println("found cssSelector:" + selector);
707 | return new RichElement("cssSelector", "[alt='" + elements.get(0).getAttribute("alt") + "']");
708 | }
709 | } catch (InvalidSelectorException | NullPointerException e) {
710 | }
711 |
712 | String root = js.executeScript("return document.domain;").toString();
713 |
714 | //href
715 | try {
716 | selector = "[href='" + webElement.getAttribute("href") + "']";
717 | elements = driver.findElements(By.cssSelector(selector));
718 | if ((elements.size() == 1) && elements.contains(webElement)) {
719 | //System.out.println("found cssSelector:" + selector);
720 | return new RichElement("cssSelector", "[href='" + elements.get(0).getAttribute("href") + "']");
721 | }
722 | } catch (InvalidSelectorException | NullPointerException e) {
723 | }
724 |
725 | //href, no path
726 | try {
727 | selector = "[href='" + webElement.getAttribute("href").replaceAll("http.*" + root + "/", "") + "']";
728 | elements = driver.findElements(By.cssSelector(selector));
729 | if ((elements.size() == 1) && elements.contains(webElement)) {
730 | //System.out.println("found cssSelector:" + selector);
731 | return new RichElement("cssSelector", "[href='" + elements.get(0).getAttribute("href").replaceAll("http.*" + root + "/", "") + "']");
732 | }
733 | } catch (InvalidSelectorException | NullPointerException e) {
734 | }
735 |
736 | //href, relative path
737 | try {
738 | selector = "[href='" + webElement.getAttribute("href").replaceAll("http.*" + root, "") + "']";
739 | elements = driver.findElements(By.cssSelector(selector));
740 | if ((elements.size() == 1) && elements.contains(webElement)) {
741 | //System.out.println("found cssSelector:" + selector);
742 | return new RichElement("cssSelector", "[href='" + elements.get(0).getAttribute("href").replaceAll("http.*" + root, "") + "']");
743 | }
744 | } catch (InvalidSelectorException | NullPointerException e) {
745 | }
746 |
747 | //src
748 | try {
749 | selector = "[src='" + webElement.getAttribute("src") + "']";
750 | elements = driver.findElements(By.cssSelector(selector));
751 | if ((elements.size() == 1) && elements.contains(webElement)) {
752 | //System.out.println("found cssSelector:" + selector);
753 | return new RichElement("cssSelector", "[src='" + elements.get(0).getAttribute("src") + "']");
754 | }
755 | } catch (InvalidSelectorException | NullPointerException e) {
756 | }
757 |
758 | //src, no path
759 | try {
760 | selector = "[src='" + webElement.getAttribute("src").replaceAll("http.*" + root + "/", "") + "']";
761 | elements = driver.findElements(By.cssSelector(selector));
762 | if ((elements.size() == 1) && elements.contains(webElement)) {
763 | //System.out.println("found cssSelector:" + selector);
764 | return new RichElement("cssSelector", "[src='" + elements.get(0).getAttribute("src").replaceAll("http.*" + root + "/", "") + "']");
765 | }
766 | } catch (InvalidSelectorException | NullPointerException e) {
767 | }
768 |
769 | //src, relative path
770 | try {
771 | selector = "[src='" + webElement.getAttribute("src").replaceAll("http.*" + root, "") + "']";
772 | elements = driver.findElements(By.cssSelector(selector));
773 | if ((elements.size() == 1) && elements.contains(webElement)) {
774 | //System.out.println("found cssSelector:" + selector);
775 | return new RichElement("cssSelector", "[src='" + elements.get(0).getAttribute("src").replaceAll("http.*" + root, "") + "']");
776 | }
777 | } catch (InvalidSelectorException | NullPointerException e) {
778 | }
779 |
780 | //title
781 | try {
782 | selector = "[title='" + webElement.getAttribute("title") + "']";
783 | elements = driver.findElements(By.cssSelector(selector));
784 | if ((elements.size() == 1) && elements.contains(webElement)) {
785 | //System.out.println("found cssSelector:" + selector);
786 | return new RichElement("cssSelector", "[title='" + elements.get(0).getAttribute("title") + "']");
787 | }
788 | } catch (InvalidSelectorException | NullPointerException e) {
789 | }
790 |
791 | //classname
792 | try {
793 | elements = driver.findElements(By.className(webElement.getAttribute("className")));
794 | if ((elements.size() == 1) && elements.contains(webElement)) {
795 | //System.out.println("found className:" + elements.get(0).getAttribute("className"));
796 | return new RichElement("className", elements.get(0).getAttribute("className"));
797 | }
798 | } catch (InvalidSelectorException | NullPointerException e) {
799 | }
800 |
801 | try {
802 | selector = "." + webElement.getAttribute("className").replace(" ", ".");
803 | elements = driver.findElements(By.cssSelector(selector));
804 | if ((elements.size() == 1) && elements.contains(webElement)) {
805 | //System.out.println("found cssSelector:" + selector);
806 | return new RichElement("className", "." + elements.get(0).getAttribute("className").replace(" ", "."));
807 | }
808 | } catch (InvalidSelectorException | NullPointerException e) {
809 | }
810 |
811 | //class
812 | try {
813 | selector = "[class='" + webElement.getAttribute("class") + "']";
814 | elements = driver.findElements(By.cssSelector(selector));
815 | if ((elements.size() == 1) && elements.contains(webElement)) {
816 | //System.out.println("found cssSelector:" + selector);
817 | return new RichElement("cssSelector", "[class='" + elements.get(0).getAttribute("class") + "']");
818 | }
819 | } catch (InvalidSelectorException | NullPointerException e) {
820 | }
821 |
822 | //type
823 | try {
824 | selector = "[type='" + webElement.getAttribute("type") + "']";
825 | elements = driver.findElements(By.cssSelector(selector));
826 | if ((elements.size() == 1) && elements.contains(webElement)) {
827 | //System.out.println("found cssSelector:" + selector);
828 | return new RichElement("cssSelector", "[type='" + elements.get(0).getAttribute("type") + "']");
829 | }
830 | } catch (InvalidSelectorException | NullPointerException e) {
831 | }
832 |
833 | //value
834 | try {
835 | selector = "[value='" + webElement.getAttribute("value") + "']";
836 | elements = driver.findElements(By.cssSelector(selector));
837 | if ((elements.size() == 1) && elements.contains(webElement)) {
838 | //System.out.println("found cssSelector:" + selector);
839 | return new RichElement("cssSelector", "[value='" + elements.get(0).getAttribute("value") + "']");
840 | }
841 | } catch (InvalidSelectorException | NullPointerException e) {
842 | }
843 |
844 | //custom CSS selectors
845 | for (String item : CSSselectors) {
846 | try {
847 | elements = driver.findElements(By.cssSelector(item));
848 | //System.out.println("len:" + elements.size());
849 | if ((elements.size() == 1) && elements.contains(webElement)) {
850 | return new RichElement("cssSelector", item.replace("\"", "\\\""));
851 | }
852 | } catch (InvalidSelectorException | NullPointerException e) {
853 | }
854 | }
855 |
856 | //implement other methods?
857 | return new RichElement(null, null);
858 | }
859 |
860 | }
861 |
--------------------------------------------------------------------------------
/src/main/java/objectivetester/Wisard.form:
--------------------------------------------------------------------------------
1 |
2 |
3 |
730 |
--------------------------------------------------------------------------------
/src/main/java/objectivetester/Wisard.java:
--------------------------------------------------------------------------------
1 | package objectivetester;
2 |
3 | import java.awt.Color;
4 | import java.awt.Cursor;
5 | import java.awt.Desktop;
6 | import java.awt.event.ActionListener;
7 | import java.awt.event.MouseListener;
8 | import java.awt.event.WindowAdapter;
9 | import java.awt.event.WindowEvent;
10 | import java.io.IOException;
11 | import java.io.OutputStream;
12 | import java.io.PrintStream;
13 | import java.net.URI;
14 | import java.net.URISyntaxException;
15 | import java.util.prefs.Preferences;
16 | import javax.swing.ImageIcon;
17 | import javax.swing.JFrame;
18 | import javax.swing.JMenuItem;
19 | import javax.swing.JOptionPane;
20 | import javax.swing.JPopupMenu;
21 | import javax.swing.text.BadLocationException;
22 | import com.formdev.flatlaf.FlatLightLaf;
23 | import com.formdev.flatlaf.FlatDarkLaf;
24 |
25 | /**
26 | *
27 | * @author Steve
28 | */
29 | public class Wisard extends javax.swing.JFrame implements UserInterface {
30 | //Web Internal Structure Action RecorDer
31 |
32 | private ImageIcon icon;
33 | private final javax.swing.table.DefaultTableModel jTable1Model;
34 | private final JPopupMenu popup;
35 | private final BrowserDriver bd = new BrowserDriver(this);
36 | private final Preferences prefs;
37 |
38 | /**
39 | * Creates new form Wisard
40 | */
41 | public Wisard() {
42 | icon = new ImageIcon(getClass().getResource("/images/wisard.png"));
43 | //create the tablemodel for the element table
44 | jTable1Model = new javax.swing.table.DefaultTableModel(
45 | new Object[][]{},
46 | new String[]{
47 | "Element", "Location", "Name", "id", "Value", "webElement"
48 | }) {
49 | boolean[] canEdit = new boolean[]{
50 | false, false, false, false, false, false
51 | };
52 |
53 | @Override
54 | public boolean isCellEditable(int rowIndex, int columnIndex) {
55 | return canEdit[columnIndex];
56 | }
57 | };
58 |
59 | initComponents();
60 |
61 | //redirect output to text area
62 | PrintStream printStream = new PrintStream(new OutputStream() {
63 | @Override
64 | public void write(int b) throws IOException {
65 | textConsole.append(String.valueOf((char) b));
66 | textConsole.setCaretPosition(textConsole.getDocument().getLength());
67 | }
68 | });
69 | System.setOut(printStream);
70 | System.setErr(printStream);
71 |
72 | //create the popup menu for the element table
73 | popup = new JPopupMenu();
74 | MouseListener popupListener = new EventListener(popup, tableElements, bd);
75 |
76 | JMenuItem menuItem = new JMenuItem(Const.CLICK);
77 | menuItem.addActionListener((ActionListener) popupListener);
78 | popup.add(menuItem);
79 | menuItem = new JMenuItem(Const.FIND);
80 | menuItem.addActionListener((ActionListener) popupListener);
81 | popup.add(menuItem);
82 | menuItem = new JMenuItem(Const.ASSERT);
83 | menuItem.addActionListener((ActionListener) popupListener);
84 | popup.add(menuItem);
85 | menuItem = new JMenuItem(Const.IDENTIFY);
86 | menuItem.addActionListener((ActionListener) popupListener);
87 | popup.add(menuItem);
88 | tableElements.addMouseListener(popupListener);
89 | //hide the webElements
90 | tableElements.removeColumn(tableElements.getColumn("webElement"));
91 |
92 | this.addWindowListener(new WindowAdapter() {
93 | @Override
94 | public void windowClosing(WindowEvent event) {
95 | exitProcedure();
96 | }
97 | });
98 |
99 | //get prefs
100 | prefs = Preferences.userRoot().node("wisard");
101 | if (prefs.get("browser", "").contentEquals("")) {
102 | //System.out.println("no prefs, writing defaults");
103 | prefs.put("browser", "FF");
104 | prefs.put("output", "junit");
105 | prefs.put("driverFF", "");
106 | prefs.put("driverCR", "");
107 | prefs.put("driverED", "");
108 | prefs.putBoolean("showId", false);
109 | prefs.putBoolean("showInvis", false);
110 | prefs.put("defaultURL", "http://www.saucedemo.com");
111 | }
112 | pathFF.setText(prefs.get("driverFF", ""));
113 | pathCR.setText(prefs.get("driverCR", ""));
114 | pathED.setText(prefs.get("driverED", ""));
115 | defaultURL.setText(prefs.get("defaultURL", ""));
116 | currentUrl.setText(prefs.get("defaultURL", ""));
117 | CSSselectors.setText(prefs.get("cssselectors", "div[id=shopping_cart_container], div[class=cart_quantity]"));
118 | if (prefs.get("browser", "").contentEquals("FF")) {
119 | buttonFF.setSelected(true);
120 | }
121 | if (prefs.get("browser", "").contentEquals("CR")) {
122 | buttonCR.setSelected(true);
123 | }
124 | if (prefs.get("browser", "").contentEquals("ED")) {
125 | buttonED.setSelected(true);
126 | }
127 | if (prefs.get("browser", "").contentEquals("SA")) {
128 | buttonSA.setSelected(true);
129 | }
130 | if (prefs.getBoolean("showId", false)) {
131 | checkBoxId.setSelected(true);
132 | } else {
133 | //hide id column
134 | tableElements.removeColumn(tableElements.getColumn("id"));
135 | }
136 | if (prefs.get("output", "").contentEquals("java")) {
137 | buttonJava.setSelected(true);
138 | }
139 | if (prefs.get("output", "").contentEquals("junit")) {
140 | buttonJunit.setSelected(true);
141 | }
142 | if (prefs.get("output", "").contentEquals("junit5")) {
143 | buttonJunit5.setSelected(true);
144 | }
145 | if (prefs.get("output", "").contentEquals("js")) {
146 | buttonJs.setSelected(true);
147 | }
148 | }
149 |
150 | /**
151 | * This method is called from within the constructor to initialise the form.
152 | * WARNING: Do NOT modify this code. The content of this method is always
153 | * regenerated by the Form Editor.
154 | */
155 | // //GEN-BEGIN:initComponents
156 | private void initComponents() {
157 | java.awt.GridBagConstraints gridBagConstraints;
158 |
159 | buttonsBrowser = new javax.swing.ButtonGroup();
160 | buttonsOutput = new javax.swing.ButtonGroup();
161 | dialogAbout = new javax.swing.JDialog();
162 | panelAbout = new javax.swing.JPanel();
163 | labelName = new javax.swing.JLabel();
164 | labelDesc = new javax.swing.JLabel();
165 | labelCopyright = new javax.swing.JLabel();
166 | labelLink = new javax.swing.JLabel();
167 | buttonCool = new javax.swing.JButton();
168 | dialogSettings = new javax.swing.JDialog();
169 | panelSettings = new javax.swing.JPanel();
170 | labelDefurl = new javax.swing.JLabel();
171 | defaultURL = new javax.swing.JTextField();
172 | labelDispopts = new javax.swing.JLabel();
173 | checkBoxId = new javax.swing.JCheckBox();
174 | checkBoxInvis = new javax.swing.JCheckBox();
175 | labelOutput = new javax.swing.JLabel();
176 | buttonJunit = new javax.swing.JRadioButton();
177 | buttonJunit5 = new javax.swing.JRadioButton();
178 | buttonJava = new javax.swing.JRadioButton();
179 | buttonJs = new javax.swing.JRadioButton();
180 | labelDriver = new javax.swing.JLabel();
181 | buttonFF = new javax.swing.JRadioButton();
182 | buttonCR = new javax.swing.JRadioButton();
183 | buttonED = new javax.swing.JRadioButton();
184 | buttonSA = new javax.swing.JRadioButton();
185 | pathFF = new javax.swing.JTextField();
186 | pathCR = new javax.swing.JTextField();
187 | labelPlugin = new javax.swing.JLabel();
188 | buttonSave = new javax.swing.JButton();
189 | buttonCancel = new javax.swing.JButton();
190 | pathED = new javax.swing.JTextField();
191 | labelCSS = new javax.swing.JLabel();
192 | CSSselectors = new javax.swing.JTextField();
193 | jToolBar1 = new javax.swing.JToolBar();
194 | labelUrl = new javax.swing.JLabel();
195 | currentUrl = new javax.swing.JTextField();
196 | buttonInspect = new javax.swing.JToggleButton();
197 | buttonRefresh = new javax.swing.JButton();
198 | jSplitPane1 = new javax.swing.JSplitPane();
199 | panelElements = new javax.swing.JPanel();
200 | paneElements = new javax.swing.JScrollPane();
201 | tableElements = new javax.swing.JTable();
202 | tableElements.getTableHeader().setReorderingAllowed(false);
203 | paneCode = new javax.swing.JScrollPane();
204 | code = new javax.swing.JTextArea();
205 | paneConsole = new javax.swing.JScrollPane();
206 | textConsole = new javax.swing.JTextArea();
207 | menuBar = new javax.swing.JMenuBar();
208 | menuFile = new javax.swing.JMenu();
209 | menuExit = new javax.swing.JMenuItem();
210 | menuEdit = new javax.swing.JMenu();
211 | menuSettings = new javax.swing.JMenuItem();
212 | menuHelp = new javax.swing.JMenu();
213 | menuAbout = new javax.swing.JMenuItem();
214 |
215 | dialogAbout.setTitle("About");
216 | dialogAbout.setIconImage(icon.getImage());
217 | dialogAbout.setMinimumSize(new java.awt.Dimension(400, 400));
218 | dialogAbout.setModal(true);
219 |
220 | panelAbout.setLayout(new java.awt.GridBagLayout());
221 |
222 | labelName.setFont(new java.awt.Font("Tahoma", 0, 72)); // NOI18N
223 | labelName.setText("Wisard");
224 | gridBagConstraints = new java.awt.GridBagConstraints();
225 | gridBagConstraints.gridx = 0;
226 | gridBagConstraints.gridy = 0;
227 | panelAbout.add(labelName, gridBagConstraints);
228 |
229 | labelDesc.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
230 | labelDesc.setText("Web Internal Structure Action RecorDer");
231 | gridBagConstraints = new java.awt.GridBagConstraints();
232 | gridBagConstraints.gridx = 0;
233 | gridBagConstraints.gridy = 1;
234 | panelAbout.add(labelDesc, gridBagConstraints);
235 |
236 | labelCopyright.setText("© Steve Mellor 2014-2023");
237 | gridBagConstraints = new java.awt.GridBagConstraints();
238 | gridBagConstraints.gridx = 0;
239 | gridBagConstraints.gridy = 2;
240 | panelAbout.add(labelCopyright, gridBagConstraints);
241 |
242 | labelLink.setText(" Wisard on github");
243 | labelLink.setToolTipText("");
244 | labelLink.addMouseListener(new java.awt.event.MouseAdapter() {
245 | public void mouseClicked(java.awt.event.MouseEvent evt) {
246 | labelLinkMouseClicked(evt);
247 | }
248 | public void mouseEntered(java.awt.event.MouseEvent evt) {
249 | labelLinkMouseEntered(evt);
250 | }
251 | });
252 | gridBagConstraints = new java.awt.GridBagConstraints();
253 | gridBagConstraints.gridx = 0;
254 | gridBagConstraints.gridy = 3;
255 | panelAbout.add(labelLink, gridBagConstraints);
256 |
257 | buttonCool.setText("Cool");
258 | buttonCool.addActionListener(new java.awt.event.ActionListener() {
259 | public void actionPerformed(java.awt.event.ActionEvent evt) {
260 | buttonCoolActionPerformed(evt);
261 | }
262 | });
263 | gridBagConstraints = new java.awt.GridBagConstraints();
264 | gridBagConstraints.gridx = 0;
265 | gridBagConstraints.gridy = 4;
266 | gridBagConstraints.insets = new java.awt.Insets(14, 0, 0, 0);
267 | panelAbout.add(buttonCool, gridBagConstraints);
268 |
269 | javax.swing.GroupLayout dialogAboutLayout = new javax.swing.GroupLayout(dialogAbout.getContentPane());
270 | dialogAbout.getContentPane().setLayout(dialogAboutLayout);
271 | dialogAboutLayout.setHorizontalGroup(
272 | dialogAboutLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
273 | .addGroup(dialogAboutLayout.createSequentialGroup()
274 | .addGap(0, 0, Short.MAX_VALUE)
275 | .addComponent(panelAbout, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
276 | .addGap(0, 0, Short.MAX_VALUE))
277 | );
278 | dialogAboutLayout.setVerticalGroup(
279 | dialogAboutLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
280 | .addGroup(dialogAboutLayout.createSequentialGroup()
281 | .addGap(0, 0, Short.MAX_VALUE)
282 | .addComponent(panelAbout, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
283 | .addGap(0, 0, Short.MAX_VALUE))
284 | );
285 |
286 | dialogSettings.setTitle("Settings");
287 | dialogSettings.setIconImage(icon.getImage());
288 | dialogSettings.setMinimumSize(new java.awt.Dimension(500, 500));
289 | dialogSettings.setModal(true);
290 |
291 | panelSettings.setLayout(new java.awt.GridBagLayout());
292 |
293 | labelDefurl.setText("Default URL");
294 | gridBagConstraints = new java.awt.GridBagConstraints();
295 | gridBagConstraints.gridx = 0;
296 | gridBagConstraints.gridy = 1;
297 | gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
298 | panelSettings.add(labelDefurl, gridBagConstraints);
299 |
300 | defaultURL.setColumns(20);
301 | defaultURL.setText("defaultURL");
302 | defaultURL.setToolTipText("Default URL");
303 | defaultURL.setMinimumSize(new java.awt.Dimension(166, 20));
304 | defaultURL.setName(""); // NOI18N
305 | gridBagConstraints = new java.awt.GridBagConstraints();
306 | gridBagConstraints.gridx = 1;
307 | gridBagConstraints.gridy = 1;
308 | gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
309 | gridBagConstraints.ipadx = 100;
310 | gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
311 | panelSettings.add(defaultURL, gridBagConstraints);
312 | defaultURL.getAccessibleContext().setAccessibleName("Default URL");
313 |
314 | labelDispopts.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
315 | labelDispopts.setText("Display Options");
316 | gridBagConstraints = new java.awt.GridBagConstraints();
317 | gridBagConstraints.gridx = 0;
318 | gridBagConstraints.gridy = 3;
319 | gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
320 | gridBagConstraints.insets = new java.awt.Insets(20, 0, 0, 0);
321 | panelSettings.add(labelDispopts, gridBagConstraints);
322 |
323 | checkBoxId.setText("Show Element 'id'");
324 | checkBoxId.setToolTipText("Show Element 'id'");
325 | gridBagConstraints = new java.awt.GridBagConstraints();
326 | gridBagConstraints.gridx = 0;
327 | gridBagConstraints.gridy = 4;
328 | gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
329 | panelSettings.add(checkBoxId, gridBagConstraints);
330 | checkBoxId.getAccessibleContext().setAccessibleDescription("Show id");
331 |
332 | checkBoxInvis.setText("List invisible Elements");
333 | checkBoxInvis.setToolTipText("List invisible Elements");
334 | gridBagConstraints = new java.awt.GridBagConstraints();
335 | gridBagConstraints.gridx = 0;
336 | gridBagConstraints.gridy = 5;
337 | gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
338 | panelSettings.add(checkBoxInvis, gridBagConstraints);
339 | checkBoxInvis.getAccessibleContext().setAccessibleDescription("List Invisible");
340 |
341 | labelOutput.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
342 | labelOutput.setText("Generated Output");
343 | gridBagConstraints = new java.awt.GridBagConstraints();
344 | gridBagConstraints.gridx = 0;
345 | gridBagConstraints.gridy = 6;
346 | gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
347 | gridBagConstraints.insets = new java.awt.Insets(20, 0, 0, 0);
348 | panelSettings.add(labelOutput, gridBagConstraints);
349 |
350 | buttonsOutput.add(buttonJunit);
351 | buttonJunit.setText("JUnit");
352 | gridBagConstraints = new java.awt.GridBagConstraints();
353 | gridBagConstraints.gridx = 0;
354 | gridBagConstraints.gridy = 7;
355 | gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
356 | panelSettings.add(buttonJunit, gridBagConstraints);
357 |
358 | buttonsOutput.add(buttonJunit5);
359 | buttonJunit5.setText("JUnit5");
360 | gridBagConstraints = new java.awt.GridBagConstraints();
361 | gridBagConstraints.gridx = 0;
362 | gridBagConstraints.gridy = 8;
363 | gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
364 | panelSettings.add(buttonJunit5, gridBagConstraints);
365 |
366 | buttonsOutput.add(buttonJava);
367 | buttonJava.setText("Java");
368 | gridBagConstraints = new java.awt.GridBagConstraints();
369 | gridBagConstraints.gridx = 0;
370 | gridBagConstraints.gridy = 9;
371 | gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
372 | panelSettings.add(buttonJava, gridBagConstraints);
373 |
374 | buttonsOutput.add(buttonJs);
375 | buttonJs.setText("JavaScript");
376 | gridBagConstraints = new java.awt.GridBagConstraints();
377 | gridBagConstraints.gridx = 0;
378 | gridBagConstraints.gridy = 10;
379 | gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
380 | panelSettings.add(buttonJs, gridBagConstraints);
381 |
382 | labelDriver.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
383 | labelDriver.setText("Target Browser and driver");
384 | gridBagConstraints = new java.awt.GridBagConstraints();
385 | gridBagConstraints.gridx = 0;
386 | gridBagConstraints.gridy = 11;
387 | gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
388 | gridBagConstraints.insets = new java.awt.Insets(20, 0, 0, 20);
389 | panelSettings.add(labelDriver, gridBagConstraints);
390 |
391 | buttonsBrowser.add(buttonFF);
392 | buttonFF.setText("Firefox");
393 | gridBagConstraints = new java.awt.GridBagConstraints();
394 | gridBagConstraints.gridx = 0;
395 | gridBagConstraints.gridy = 12;
396 | gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
397 | panelSettings.add(buttonFF, gridBagConstraints);
398 |
399 | buttonsBrowser.add(buttonCR);
400 | buttonCR.setText("Chrome");
401 | gridBagConstraints = new java.awt.GridBagConstraints();
402 | gridBagConstraints.gridx = 0;
403 | gridBagConstraints.gridy = 14;
404 | gridBagConstraints.gridheight = 2;
405 | gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
406 | panelSettings.add(buttonCR, gridBagConstraints);
407 |
408 | buttonsBrowser.add(buttonED);
409 | buttonED.setText("Edge");
410 | gridBagConstraints = new java.awt.GridBagConstraints();
411 | gridBagConstraints.gridx = 0;
412 | gridBagConstraints.gridy = 18;
413 | gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
414 | panelSettings.add(buttonED, gridBagConstraints);
415 |
416 | buttonsBrowser.add(buttonSA);
417 | buttonSA.setText("Safari");
418 | gridBagConstraints = new java.awt.GridBagConstraints();
419 | gridBagConstraints.gridx = 0;
420 | gridBagConstraints.gridy = 20;
421 | gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
422 | panelSettings.add(buttonSA, gridBagConstraints);
423 |
424 | pathFF.setColumns(20);
425 | pathFF.setText("pathFF");
426 | pathFF.setToolTipText("Path to Gecko driver");
427 | pathFF.setName(""); // NOI18N
428 | gridBagConstraints = new java.awt.GridBagConstraints();
429 | gridBagConstraints.gridx = 1;
430 | gridBagConstraints.gridy = 12;
431 | gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
432 | gridBagConstraints.ipadx = 100;
433 | gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
434 | panelSettings.add(pathFF, gridBagConstraints);
435 |
436 | pathCR.setColumns(20);
437 | pathCR.setText("pathCR");
438 | pathCR.setToolTipText("Path to Chrome driver");
439 | gridBagConstraints = new java.awt.GridBagConstraints();
440 | gridBagConstraints.gridx = 1;
441 | gridBagConstraints.gridy = 14;
442 | gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
443 | gridBagConstraints.ipadx = 100;
444 | gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
445 | panelSettings.add(pathCR, gridBagConstraints);
446 | pathCR.getAccessibleContext().setAccessibleName("Chrome driver");
447 |
448 | labelPlugin.setFont(new java.awt.Font("Tahoma", 2, 11)); // NOI18N
449 | labelPlugin.setText("/usr/bin/safaridriver");
450 | gridBagConstraints = new java.awt.GridBagConstraints();
451 | gridBagConstraints.gridx = 1;
452 | gridBagConstraints.gridy = 20;
453 | panelSettings.add(labelPlugin, gridBagConstraints);
454 |
455 | buttonSave.setText("Save");
456 | buttonSave.addActionListener(new java.awt.event.ActionListener() {
457 | public void actionPerformed(java.awt.event.ActionEvent evt) {
458 | buttonSaveActionPerformed(evt);
459 | }
460 | });
461 | gridBagConstraints = new java.awt.GridBagConstraints();
462 | gridBagConstraints.gridx = 0;
463 | gridBagConstraints.gridy = 22;
464 | gridBagConstraints.insets = new java.awt.Insets(20, 0, 0, 0);
465 | panelSettings.add(buttonSave, gridBagConstraints);
466 |
467 | buttonCancel.setText("Cancel");
468 | buttonCancel.addActionListener(new java.awt.event.ActionListener() {
469 | public void actionPerformed(java.awt.event.ActionEvent evt) {
470 | buttonCancelActionPerformed(evt);
471 | }
472 | });
473 | gridBagConstraints = new java.awt.GridBagConstraints();
474 | gridBagConstraints.gridx = 1;
475 | gridBagConstraints.gridy = 22;
476 | gridBagConstraints.insets = new java.awt.Insets(20, 0, 0, 0);
477 | panelSettings.add(buttonCancel, gridBagConstraints);
478 |
479 | pathED.setColumns(20);
480 | pathED.setText("pathED");
481 | pathED.setToolTipText("Path to Edge driver");
482 | gridBagConstraints = new java.awt.GridBagConstraints();
483 | gridBagConstraints.gridx = 1;
484 | gridBagConstraints.gridy = 18;
485 | gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
486 | gridBagConstraints.ipadx = 100;
487 | gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
488 | panelSettings.add(pathED, gridBagConstraints);
489 |
490 | labelCSS.setText("CSS selectors");
491 | gridBagConstraints = new java.awt.GridBagConstraints();
492 | gridBagConstraints.gridx = 0;
493 | gridBagConstraints.gridy = 2;
494 | gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
495 | gridBagConstraints.insets = new java.awt.Insets(20, 0, 0, 20);
496 | panelSettings.add(labelCSS, gridBagConstraints);
497 |
498 | CSSselectors.setColumns(20);
499 | CSSselectors.setText("CSSselectors");
500 | CSSselectors.setToolTipText("comma seperated list of selectors");
501 | CSSselectors.setMinimumSize(new java.awt.Dimension(166, 24));
502 | gridBagConstraints = new java.awt.GridBagConstraints();
503 | gridBagConstraints.gridx = 1;
504 | gridBagConstraints.gridy = 2;
505 | gridBagConstraints.ipadx = 100;
506 | gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
507 | gridBagConstraints.insets = new java.awt.Insets(20, 0, 0, 0);
508 | panelSettings.add(CSSselectors, gridBagConstraints);
509 |
510 | javax.swing.GroupLayout dialogSettingsLayout = new javax.swing.GroupLayout(dialogSettings.getContentPane());
511 | dialogSettings.getContentPane().setLayout(dialogSettingsLayout);
512 | dialogSettingsLayout.setHorizontalGroup(
513 | dialogSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
514 | .addGap(0, 400, Short.MAX_VALUE)
515 | .addGroup(dialogSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
516 | .addComponent(panelSettings, javax.swing.GroupLayout.PREFERRED_SIZE, 400, Short.MAX_VALUE))
517 | );
518 | dialogSettingsLayout.setVerticalGroup(
519 | dialogSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
520 | .addGap(0, 450, Short.MAX_VALUE)
521 | .addGroup(dialogSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
522 | .addComponent(panelSettings, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
523 | );
524 |
525 | setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
526 | setTitle("Wisard");
527 | setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
528 | setIconImage(icon.getImage());
529 |
530 | jToolBar1.setRollover(true);
531 |
532 | labelUrl.setText("URL");
533 | jToolBar1.add(labelUrl);
534 |
535 | currentUrl.setColumns(15);
536 | currentUrl.setText("URL");
537 | currentUrl.setToolTipText("Website URL");
538 | currentUrl.setCursor(new java.awt.Cursor(java.awt.Cursor.TEXT_CURSOR));
539 | currentUrl.setMinimumSize(new java.awt.Dimension(6, 15));
540 | currentUrl.setPreferredSize(new java.awt.Dimension(12, 20));
541 | currentUrl.addActionListener(new java.awt.event.ActionListener() {
542 | public void actionPerformed(java.awt.event.ActionEvent evt) {
543 | currentUrlActionPerformed(evt);
544 | }
545 | });
546 | jToolBar1.add(currentUrl);
547 | currentUrl.getAccessibleContext().setAccessibleName("URL");
548 |
549 | buttonInspect.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/inspect.png"))); // NOI18N
550 | buttonInspect.setToolTipText("Open the URL");
551 | buttonInspect.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
552 | buttonInspect.setFocusable(false);
553 | buttonInspect.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
554 | buttonInspect.setSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/images/cancel.png"))); // NOI18N
555 | buttonInspect.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
556 | buttonInspect.addActionListener(new java.awt.event.ActionListener() {
557 | public void actionPerformed(java.awt.event.ActionEvent evt) {
558 | buttonInspectActionPerformed(evt);
559 | }
560 | });
561 | jToolBar1.add(buttonInspect);
562 |
563 | buttonRefresh.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/refresh.png"))); // NOI18N
564 | buttonRefresh.setToolTipText("Refresh the page elements list");
565 | buttonRefresh.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
566 | buttonRefresh.setFocusable(false);
567 | buttonRefresh.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
568 | buttonRefresh.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
569 | buttonRefresh.addActionListener(new java.awt.event.ActionListener() {
570 | public void actionPerformed(java.awt.event.ActionEvent evt) {
571 | buttonRefreshActionPerformed(evt);
572 | }
573 | });
574 | jToolBar1.add(buttonRefresh);
575 |
576 | getContentPane().add(jToolBar1, java.awt.BorderLayout.PAGE_START);
577 |
578 | panelElements.setPreferredSize(new java.awt.Dimension(300, 300));
579 | panelElements.setLayout(new java.awt.BorderLayout());
580 |
581 | paneElements.setPreferredSize(new java.awt.Dimension(300, 300));
582 |
583 | tableElements.setModel(jTable1Model);
584 | tableElements.setColumnSelectionAllowed(true);
585 | tableElements.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
586 | paneElements.setViewportView(tableElements);
587 | tableElements.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
588 |
589 | panelElements.add(paneElements, java.awt.BorderLayout.CENTER);
590 |
591 | jSplitPane1.setLeftComponent(panelElements);
592 |
593 | code.setEditable(false);
594 | code.setColumns(20);
595 | code.setFont(new java.awt.Font("Courier New", 0, 12)); // NOI18N
596 | code.setRows(5);
597 | code.setTabSize(4);
598 | paneCode.setViewportView(code);
599 |
600 | jSplitPane1.setRightComponent(paneCode);
601 |
602 | getContentPane().add(jSplitPane1, java.awt.BorderLayout.CENTER);
603 |
604 | textConsole.setEditable(false);
605 | textConsole.setColumns(20);
606 | textConsole.setFont(new java.awt.Font("Courier New", 0, 12)); // NOI18N
607 | textConsole.setRows(5);
608 | paneConsole.setViewportView(textConsole);
609 |
610 | getContentPane().add(paneConsole, java.awt.BorderLayout.PAGE_END);
611 |
612 | menuFile.setText("File");
613 |
614 | menuExit.setText("Exit");
615 | menuExit.addActionListener(new java.awt.event.ActionListener() {
616 | public void actionPerformed(java.awt.event.ActionEvent evt) {
617 | menuExitActionPerformed(evt);
618 | }
619 | });
620 | menuFile.add(menuExit);
621 |
622 | menuBar.add(menuFile);
623 |
624 | menuEdit.setText("Edit");
625 |
626 | menuSettings.setText("Settings");
627 | menuSettings.addActionListener(new java.awt.event.ActionListener() {
628 | public void actionPerformed(java.awt.event.ActionEvent evt) {
629 | menuSettingsActionPerformed(evt);
630 | }
631 | });
632 | menuEdit.add(menuSettings);
633 |
634 | menuBar.add(menuEdit);
635 |
636 | menuHelp.setText("Help");
637 |
638 | menuAbout.setText("About");
639 | menuAbout.addActionListener(new java.awt.event.ActionListener() {
640 | public void actionPerformed(java.awt.event.ActionEvent evt) {
641 | menuAboutActionPerformed(evt);
642 | }
643 | });
644 | menuHelp.add(menuAbout);
645 |
646 | menuBar.add(menuHelp);
647 |
648 | setJMenuBar(menuBar);
649 |
650 | pack();
651 | }// //GEN-END:initComponents
652 |
653 | private void currentUrlActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_currentUrlActionPerformed
654 | buttonInspect.doClick();
655 | }//GEN-LAST:event_currentUrlActionPerformed
656 |
657 | private void buttonSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSaveActionPerformed
658 |
659 | //update UI
660 | if (!buttonInspect.isSelected()) {
661 | currentUrl.setText(defaultURL.getText());
662 | }
663 | if (!prefs.getBoolean("showId", false) && checkBoxId.isSelected()) {
664 | //reset table to show id
665 | jTable1Model.fireTableStructureChanged();
666 | //re-hide webElements
667 | tableElements.removeColumn(tableElements.getColumn("webElement"));
668 | }
669 | if (prefs.getBoolean("showId", false) && !checkBoxId.isSelected()) {
670 | //hide id column
671 | tableElements.removeColumn(tableElements.getColumn("id"));
672 | }
673 |
674 | //save new settings
675 | prefs.put("defaultURL", defaultURL.getText());
676 | prefs.put("cssselectors", CSSselectors.getText());
677 |
678 | prefs.putBoolean("showId", checkBoxId.isSelected());
679 | prefs.putBoolean("showInvis", checkBoxInvis.isSelected());
680 |
681 | if (buttonFF.isSelected()) {
682 | prefs.put("browser", "FF");
683 | }
684 | if (buttonED.isSelected()) {
685 | prefs.put("browser", "ED");
686 | }
687 | if (buttonCR.isSelected()) {
688 | prefs.put("browser", "CR");
689 | }
690 | if (buttonSA.isSelected()) {
691 | prefs.put("browser", "SA");
692 | }
693 | if (buttonJunit.isSelected()) {
694 | prefs.put("output", "junit");
695 | }
696 | if (buttonJunit5.isSelected()) {
697 | prefs.put("output", "junit5");
698 | }
699 | if (buttonJava.isSelected()) {
700 | prefs.put("output", "java");
701 | }
702 | if (buttonJs.isSelected()) {
703 | prefs.put("output", "js");
704 | }
705 |
706 | prefs.put("driverFF", pathFF.getText());
707 | prefs.put("driverCR", pathCR.getText());
708 | prefs.put("driverED", pathED.getText());
709 |
710 | dialogSettings.setVisible(false);
711 | }//GEN-LAST:event_buttonSaveActionPerformed
712 |
713 | private void buttonInspectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonInspectActionPerformed
714 | // TODO add your handling code here:
715 | //System.out.println(evt.getActionCommand());
716 | if (buttonInspect.isSelected()) {
717 | currentUrl.setEnabled(false);
718 | Boolean success = false;
719 | bd.initWriter(prefs.get("output", "junit"));
720 | if (prefs.get("browser", "").contentEquals("FF")) {
721 | success = bd.initFF(currentUrl.getText(), prefs.get("driverFF", ""));
722 | }
723 | if (prefs.get("browser", "").contentEquals("CR")) {
724 | success = bd.initCR(currentUrl.getText(), prefs.get("driverCR", ""));
725 | }
726 | if (prefs.get("browser", "").contentEquals("ED")) {
727 | success = bd.initED(currentUrl.getText(), prefs.get("driverED", ""));
728 | }
729 | if (prefs.get("browser", "").contentEquals("SA")) {
730 | success = bd.initSA(currentUrl.getText());
731 | }
732 |
733 | if (success) {
734 | Thread t = new Thread(bd, "Page Examiner");
735 | t.start();
736 | } else {
737 | currentUrl.setEnabled(true);
738 | buttonInspect.doClick();
739 | bd.close();
740 | }
741 |
742 | } else {
743 | currentUrl.setEnabled(true);
744 | //tidy up
745 | popup.setVisible(false);
746 | for (int i = jTable1Model.getRowCount(); i > 0; i--) {
747 | jTable1Model.removeRow(i - 1);
748 | }
749 | bd.close();
750 | }
751 | }//GEN-LAST:event_buttonInspectActionPerformed
752 |
753 | private void buttonRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonRefreshActionPerformed
754 | rescan();
755 | }//GEN-LAST:event_buttonRefreshActionPerformed
756 |
757 | private void labelLinkMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_labelLinkMouseClicked
758 | // TODO add your handling code here:
759 | if (Desktop.isDesktopSupported()) {
760 | try {
761 | Desktop.getDesktop().browse(new URI("https://github.com/objectivetester/wisard"));
762 | } catch (URISyntaxException | IOException | UnsupportedOperationException ex) {
763 | this.errorMessage("Unable to open browser, please visit:\n https://github.com/objectivetester/wisard");
764 | }
765 | } else {
766 | this.errorMessage("Unable to open browser, please visit:\n https://github.com/objectivetester/wisard");
767 | }
768 | }//GEN-LAST:event_labelLinkMouseClicked
769 |
770 | private void labelLinkMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_labelLinkMouseEntered
771 | // TODO add your handling code here:
772 | labelLink.setCursor(new Cursor(Cursor.HAND_CURSOR));
773 | }//GEN-LAST:event_labelLinkMouseEntered
774 |
775 | private void menuExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuExitActionPerformed
776 | // TODO add your handling code here:
777 | dispose();
778 | }//GEN-LAST:event_menuExitActionPerformed
779 |
780 | private void menuSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuSettingsActionPerformed
781 | // TODO add your handling code here:
782 | dialogSettings.setVisible(true);
783 | }//GEN-LAST:event_menuSettingsActionPerformed
784 |
785 | private void menuAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuAboutActionPerformed
786 | // TODO add your handling code here:
787 | dialogAbout.setVisible(true);
788 | }//GEN-LAST:event_menuAboutActionPerformed
789 |
790 | private void buttonCoolActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonCoolActionPerformed
791 | // TODO add your handling code here:
792 | dialogAbout.setVisible(false);
793 | }//GEN-LAST:event_buttonCoolActionPerformed
794 |
795 | private void buttonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonCancelActionPerformed
796 | // TODO add your handling code here:
797 | //restore original settings
798 | defaultURL.setText((prefs.get("defaultURL", "")));
799 | checkBoxId.setSelected(prefs.getBoolean("showId", true));
800 | checkBoxInvis.setSelected(prefs.getBoolean("showInvis", true));
801 |
802 | if (prefs.get("browser", "").contentEquals("FF")) {
803 | buttonFF.setSelected(true);
804 | }
805 | if (prefs.get("browser", "").contentEquals("CR")) {
806 | buttonCR.setSelected(true);
807 | }
808 | if (prefs.get("browser", "").contentEquals("ED")) {
809 | buttonED.setSelected(true);
810 | }
811 | if (prefs.get("browser", "").contentEquals("SA")) {
812 | buttonSA.setSelected(true);
813 | }
814 |
815 | pathFF.setText(prefs.get("driverFF", ""));
816 | pathCR.setText(prefs.get("driverCR", ""));
817 | pathED.setText(prefs.get("driverED", ""));
818 |
819 | dialogSettings.setVisible(false);
820 | }//GEN-LAST:event_buttonCancelActionPerformed
821 |
822 | /**
823 | * @param args the command line arguments
824 | */
825 | public static void main(String args[]) {
826 | /* Set the look and feel */
827 | //
828 |
829 | try {
830 | //javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
831 | if (Theme.light()) {
832 | javax.swing.UIManager.setLookAndFeel("com.formdev.flatlaf.FlatLightLaf");
833 | } else {
834 | javax.swing.UIManager.setLookAndFeel("com.formdev.flatlaf.FlatDarkLaf");
835 | }
836 |
837 | // for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
838 | // if ("Nimbus".equals(info.getName())) {
839 | // javax.swing.UIManager.setLookAndFeel(info.getClassName());
840 | // break;
841 | // }
842 | // }
843 | } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
844 | }
845 | //
846 |
847 | /* Create and display the form */
848 | java.awt.EventQueue.invokeLater(new Runnable() {
849 | @Override
850 | public void run() {
851 | new Wisard().setVisible(true);
852 | }
853 | });
854 | }
855 | // Variables declaration - do not modify//GEN-BEGIN:variables
856 | private javax.swing.JTextField CSSselectors;
857 | private javax.swing.JRadioButton buttonCR;
858 | private javax.swing.JButton buttonCancel;
859 | private javax.swing.JButton buttonCool;
860 | private javax.swing.JRadioButton buttonED;
861 | private javax.swing.JRadioButton buttonFF;
862 | private javax.swing.JToggleButton buttonInspect;
863 | private javax.swing.JRadioButton buttonJava;
864 | private javax.swing.JRadioButton buttonJs;
865 | private javax.swing.JRadioButton buttonJunit;
866 | private javax.swing.JRadioButton buttonJunit5;
867 | private javax.swing.JButton buttonRefresh;
868 | private javax.swing.JRadioButton buttonSA;
869 | private javax.swing.JButton buttonSave;
870 | private javax.swing.ButtonGroup buttonsBrowser;
871 | private javax.swing.ButtonGroup buttonsOutput;
872 | private javax.swing.JCheckBox checkBoxId;
873 | private javax.swing.JCheckBox checkBoxInvis;
874 | private javax.swing.JTextArea code;
875 | private javax.swing.JTextField currentUrl;
876 | private javax.swing.JTextField defaultURL;
877 | private javax.swing.JDialog dialogAbout;
878 | private javax.swing.JDialog dialogSettings;
879 | private javax.swing.JSplitPane jSplitPane1;
880 | private javax.swing.JToolBar jToolBar1;
881 | private javax.swing.JLabel labelCSS;
882 | private javax.swing.JLabel labelCopyright;
883 | private javax.swing.JLabel labelDefurl;
884 | private javax.swing.JLabel labelDesc;
885 | private javax.swing.JLabel labelDispopts;
886 | private javax.swing.JLabel labelDriver;
887 | private javax.swing.JLabel labelLink;
888 | private javax.swing.JLabel labelName;
889 | private javax.swing.JLabel labelOutput;
890 | private javax.swing.JLabel labelPlugin;
891 | private javax.swing.JLabel labelUrl;
892 | private javax.swing.JMenuItem menuAbout;
893 | private javax.swing.JMenuBar menuBar;
894 | private javax.swing.JMenu menuEdit;
895 | private javax.swing.JMenuItem menuExit;
896 | private javax.swing.JMenu menuFile;
897 | private javax.swing.JMenu menuHelp;
898 | private javax.swing.JMenuItem menuSettings;
899 | private javax.swing.JScrollPane paneCode;
900 | private javax.swing.JScrollPane paneConsole;
901 | private javax.swing.JScrollPane paneElements;
902 | private javax.swing.JPanel panelAbout;
903 | private javax.swing.JPanel panelElements;
904 | private javax.swing.JPanel panelSettings;
905 | private javax.swing.JTextField pathCR;
906 | private javax.swing.JTextField pathED;
907 | private javax.swing.JTextField pathFF;
908 | private javax.swing.JTable tableElements;
909 | private javax.swing.JTextArea textConsole;
910 | // End of variables declaration//GEN-END:variables
911 |
912 | private void exitProcedure() {
913 | bd.close();
914 | this.dispose();
915 | System.exit(0);
916 | }
917 |
918 | @Override
919 | public void addItem(String element, Object stack, String name, String id, String value, Object webElement, Boolean displayed) {
920 | //adds content to the elements table
921 | if (Theme.light()) {
922 | tableElements.setForeground(Color.LIGHT_GRAY);
923 | } else {
924 | tableElements.setForeground(Color.GRAY);
925 | }
926 | if ((!displayed) && (prefs.getBoolean("showInvis", false))) {
927 | element = Const.INVISIBLE + element;
928 | Object item = new Object[]{element, stack, name, id, value, webElement};
929 | jTable1Model.addRow((Object[]) item);
930 | } else if (displayed) {
931 | Object item = new Object[]{element, stack, name, id, value, webElement};
932 | jTable1Model.addRow((Object[]) item);
933 | }
934 | }
935 |
936 | @Override
937 | public void rescan() {
938 | //triggers rescan of the page
939 |
940 | //tidy up first
941 | popup.setVisible(false);
942 | for (int i = jTable1Model.getRowCount(); i > 0; i--) {
943 | jTable1Model.removeRow(i - 1);
944 | }
945 |
946 | //off we go
947 | Thread t = new Thread(bd, "Page Examiner");
948 | t.start();
949 | }
950 |
951 | @Override
952 | public void abort() {
953 | //triggers a UI cleanup
954 | this.errorMessage("Unexpected error!");
955 | buttonInspect.doClick();
956 | }
957 |
958 | @Override
959 | public void addCode(String fragment) {
960 | //adds content to the generated code
961 | code.setText(fragment);
962 | }
963 |
964 | @Override
965 | public void insertCode(String fragment, int above) {
966 | //inserts content to the generated code
967 | int point;
968 | try {
969 | point = code.getLineEndOffset(code.getLineCount() - above);
970 | } catch (BadLocationException e) {
971 | point = 1;
972 | //it'll be messy
973 | }
974 | code.insert(fragment, point - 1);
975 |
976 | }
977 |
978 | @Override
979 | public boolean alertResponse(String title) {
980 | int ok = JOptionPane.showConfirmDialog(new JFrame(), title, "Alert box opened by browser", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
981 | if (ok == 0) {
982 | return true;
983 | } else {
984 | return false;
985 | }
986 | }
987 |
988 | @Override
989 | public String enterValue(String title) {
990 | return (String) JOptionPane.showInputDialog(new JFrame(), title, "Enter Value", JOptionPane.QUESTION_MESSAGE);
991 | }
992 |
993 | @Override
994 | public String enterSelection(String title, String choices[]) {
995 | return (String) JOptionPane.showInputDialog(new JFrame(), title, "Make Selection", JOptionPane.QUESTION_MESSAGE, null, choices, choices[0]);
996 | }
997 |
998 | @Override
999 | public void elementIdent(String text) {
1000 | if (text.length() > Const.MAX_SIZ) {
1001 | //crop the text
1002 | text = text.substring(0, Const.MAX_SIZ);
1003 | }
1004 | JOptionPane.showMessageDialog(new JFrame(), text, "Element Highlighted in Browser", JOptionPane.PLAIN_MESSAGE);
1005 | }
1006 |
1007 | @Override
1008 | public void errorMessage(String message) {
1009 | if (message.length() > Const.MAX_SIZ) {
1010 | //crop the text
1011 | message = message.substring(0, Const.MAX_SIZ);
1012 | }
1013 | JOptionPane.showMessageDialog(new JFrame(), message.replace(". ", ". \n"), "Error", JOptionPane.INFORMATION_MESSAGE);
1014 | }
1015 |
1016 | @Override
1017 | public void finished() {
1018 | if (Theme.light()) {
1019 | tableElements.setForeground(Color.BLACK);
1020 | } else {
1021 | tableElements.setForeground(Color.LIGHT_GRAY);
1022 | }
1023 |
1024 | }
1025 |
1026 | @Override
1027 | public String getCSSselectors() {
1028 | return prefs.get("cssselectors", "");
1029 | }
1030 |
1031 | }
1032 |
--------------------------------------------------------------------------------