Marterialize initializing Autocomplete inside Modal inside shadowroot not working - java

I´m trying to code a little chrome extension useing Materialize.
To avoid materialize interfering with the opened website i only use it inside the shadowroot which i insert into the website.
The problem only appears when trying to initialize an Autocomplete instance inside the opened Modal.
The input html looks like:
<input id="goalInput" class="col s9 autocomplete" placeholder="">
Trying to initialize:
var autocompleteInstance = M.Autocomplete.init(shadowRoot.getElementById('goalInput'));
// or
var autocompleteInstance = M.Autocomplete.init(shadowRoot.querySelectorAll('.autocomplete'));
Both queries are working and !== null;
Produces following error:
Error Picture Stackoverflow wont let me add png direktly yet:
The error happens somewhere inside materialize initialization ( i think when trying to create a dropdown or something, i might be wrong here).
I already searched for a really long time but maybe i was missing the right keywords to find the solution to my problem.

Found a workaround.
The problem was materialize.js trying to find the initialized dropdown within the normal html which excludes the shadowRoot.
_this9.dropdownEl = document.getElementById(_this9.id);
if(_this9.dropdownEl === null) {
_this9.dropdownEl = document.getElementById('shadowWrapper').shadowRoot.getElementById(_this9.id);
}
I just updated the code from materialize.js to work with my extension.

Related

Issue with HtmlUnitDriver's frame switch in Java / Issue with switching to a 'srcdoc' based iframe

I have a java program to scrape a web page, using selenium-server-standalone-3.9.1 jar.
I create org.openga.selenium.htmlunit.HtmlUnitDriver to fetch the page which contains 2 iframes inside. JavascriptEnabled is true.
I can access the page and parse ok without issues, but for some reason, switching to those frames, doesn't seem to work. Here is a snippet of the code.
driver.switchTo().defaultContent();
//The below line works fine without issues, so I'm assuming switching is succeeding.
//FYI if I give a bogus bad frame name here, it does raise an exception, which indicates that //the driver is recognizing the frame ok
driver.switchTo().frame(driver.findElement(By.id("xyz"))); //no exceptions raised
//Here, driver.getPageSource() here shows no content, just have an empty as follows
//<html>
// <head/>
// <body/>
//</html>
// So, I can't get any actually existing elements inside the iframe at all here..
// i.e. getElements() etc would return nothing..
driver.switchTo().defaultContent();
driver.getPageSource(); //shows the full page ok again..
I don't believe it's page loading issue as the full source dump from the driver does show the contents of those embedded iframes source ok. So, I don't think "wait" would help here.
What am I missing here?
Tried to use WebDriverWait to wait for frames to be available etc, no luck.

Selenium element can not be found within iframe

I am trying to retrieve a JSON element, the problem is that in the source code it doesn't exist, but I can find it via inspect element.
I have tried with
C.driver.findElement(By.id("ticket-parsed"))
and via XPath
C.driver.findElement(By.xpath("//*[#id=\"ticket_parsed\"]"));
and I can't find it.
Also
C.driver.switchTo().frame("html5-frame");
System.out.println(C.driver.findElement(By.id("ticket_parsed")));
C.driver.switchTo().defaultContent();
i get
[[ChromeDriver: chrome on XP (1f75e50635f9dd5b9535a149a027a447)] -> id: ticket_parsed]
on
driver.switchTo().frame(0) or driver.switchTo().frame(1)
i get that the frame doesn't exists
and at last i tried
WebElement frame = C.driver.findElement(By.id("html5-frame"));
C.driver.switchTo().frame(frame.getAttribute("ticket_parsed"));
an i got a null pointer exception
Here's an image of the source:
what am I doing wrong?
Well!
The element #ticket-parsed is in iFrame. So, you can click it without getting into an iframe.
Here is the code to switch to iFrame,
driver.switchTo().frame("frame_name");
or
driver.switchTo().frame(frame_index);
In your case,
driver.switchTo().frame("html5-frame");
After switching into the iframe, you can click that element using either XPath or CSS.
C.driver.findElement(By.id("ticket-parsed"))
NOTE:
After completing the operation inside the iframe, you have to again return back to the main window using the following command.
driver.switchTo().defaultContent();
I didn't found a solution with my excising setup,but i did found a js command which gets the object correctly
document.getElementById("html5-frame").contentDocument.getElementById("ticket_parsed")
you can integrate js commands like this
JavascriptExecutor js=(JavascriptExecutor)driver;
js.executeScript(*yourCommandHere*);
if you want to get the output of the command just add the word return before your command (in this specific situation it didn't work but in any other situation it did)
*TypeOfData* foo = js.executeScript(return *yourCommandHere*);
at last because of limited time i had to use unorthodox methods like taking screenshots and comparing the images if they are exactly the same
Thanks for the help

Java ScriptEngine and parent window functions

I am using the Java ScriptEngine to call a JS function from a backing bean under certain conditions in the program. The catch is that the JSF page is running in an iFrame. Although the iFrame is not the real problem at this stage, I want it to be able to browse to a new page. For this, I have used top.window.location and parent.location and they work on a button click to load the page out of the iFrame without a problem.
This is a sample of the code I'm using for this:
ScriptEngine se = new ScriptEngineManager().getEngineByName("JavaScript");
se.eval("function someFunc(){parent.location = \"www.someurl.com\";}");
Invocable invocableJS = (Invocable) se;
invocableJS.invokeFunction("someFunc");
With parent.location and top.window.location I have read that they are called from the browser itsself, and are not JavaScript. So because of this, I get the following error:
javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "parent" is not defined. (<Unknown source>#1) in <Unknown source> at line number 1
It does exactly the same with document.getElementById("someComponent") and other similar. And it seems that the error remains with sun.org.mozilla..... in Chrome, IE, and FF all together.
So the question: How can I get the JS function to possibly use the parent.location? I imagine that I would need to check for the browser used and then import or call something from there depending on the browser, but I am not sure how I should go to work to do this. Any light that can possibly be shed on this problem will be very helpful.
Thanks in advance.
I have solved this problem, by checking for the cookies before the redirect in a Javascript method, and simply calling the JS method before the page loads using onload="someMethod();" in the body tag. Everything worked out fine, by using the parent.location to navigate to the new page. Tested in FF, Chrome and IE. Thus there was also no need for the ScriptEngine in this situation.

jquery-mobile spinner loading

i tried to do that while js is creating a timetable... it shows spinner loading..
i tried to do this $.mobile.pageLoading(); $.mobile.pageLoading(true); and also tried to use this plugin http://contextllc.com/tools/jQuery-showLoading
The result is the same.. it shows spinner after he generate time table.. and i don't know why...here is where i tried to use it...
$('#timeDropList').change(function() {
$.mobile.pageLoading(false);
$('div.addedEntry').remove();
drawTemplate();
});
Are you using the right version of jQuery Mobile? Looks like they took away the pageLoading method in 1.0b1 in favor of two separate methods: showPageLoadingMsg and hidePageLoadingMsg. The last reference I see to pageLoading is in 1.0a4.1.
$('#home').live('pagebeforecreate',function(event){
alert('This page was just enhanced by jQuery Mobile!');
$.mobile.loadingMessage = "pagebeforeshow Page...";
$.mobile.showPageLoadingMsg();
});

selecting pulldown in htmlunit

I am using htmlunit in jython and am having trouble selecting a pull down link. The page I am going to has a table with other ajax links, and I can click on them and move around and it seems okay but I can't seem to figure out how to click on a pulldown menu that allows for more links on the page(this pulldown affects the ajax table so its not redirecting me or anything).
Here's my code:
selectField1 = page.getElementById("pageNumSelection")
options2 = selectField1.getOptions()
theOption3 = options2[4]
This gets the option I want, I verify its right. so I select it:
MoreOnPage = selectField1.setSelectedAttribute(theOption3, True)
and I am stuck here(not sure if selecting it works or not because I don't get any message, but I'm not sure what to do next. How do I refresh the page to see the larger list? When clicking on links all you have to do is find the link and then select linkNameVariable.click() into a variable and it works. but I'm not sure how to refresh a pulldown. when I try to use the webclient to create an xml page based on the the select variable, I still get the old page.
to make it a bit easier, I used htmlunit scripter and got some code that should work but its java and I'm not sure how to port it to jython. Here it is:
try
{
page = webClient.getPage( url );
HtmlSelect selectField1 = (HtmlSelect) page.getElementById("pageNumSelection");
List<HtmlOption> options2 = selectField1.getOptions();
HtmlOption theOption3 = null;
for(HtmlOption option: options2)
{
if(option.getText().equals("100") )
{
theOption3 = option;
break;
}
}
selectField1.setSelectedAttribute(theOption3, true );
Have a look at HtmlForm getSelectedByName
HtmlSelect htmlSelect = form.getSelectByName("stuff[1].type");
HtmlOption htmlOption = htmlSelect.getOption(3);
htmlOption.setSelected(true);
Be sure that WebClient.setJavaScriptEnabled is called. The documentation seems to indicate that it is on by default, but I think this is wrong.
Alternatively, you can use WebDriver, which is a framework that supports both HtmlUnit and Selenium. I personally find the syntax easier to deal with than HtmlUnit.
If I understand correctly, the selection of an option in the select box triggers an AJAX calls which, once finished, modifies some part of the page.
The problem here is that since AJAX is, by definition, asynchronous, you can't really know when the call is finished and when you may inspect the page again to find the new content.
HtmlUnit has a class named NicelyResynchronizingAjaxController, which you can pass an instance of to the WebClient's setAjaxController method. As indicated in the javadoc, using this ajax controller will automatically make the asynchronous calls coming from a direct user interaction synchronous instead of asynchronous. Once the setSelectedAttribute method is called, you'll thus be able to see the changed made to the original page.
The other option is to use WebClient's waitForBackgrounfJavascript method after the selection is done, and inspect he page once the background JavaScript has ended, or the timeout has been reached.
This isn't really an answer to the question because I've not used HtmlUnit much before, but you might want to look at Selenium, and in particular Selenium RC. With Selenium RC you are able to control the interactions with a page displayed in a native browser (Firefox for example). It has developer API's for Java and Python amongst others.
I understand that HtmlUnit uses its own javascript and web browser rendering engine and I'm wondering whether that may be a problem.

Categories