strange settings/options page of Chrome extension - html

I am reading a Chrome extension codes. In one of its html files (used for setting), the source code shows that there is a select element like this
<select id="hostselect"></select>
Note that there is no option element as the child of the select element. However, if I open the setting page of the extension in Chrome, there is a drop-down list corresponding to that select element, and moreover, if I use the Chrome developer tool to inspect this setting page, it shows that the select element has option children:
<select id="hostselect">
<option value="host1">host1</option>
<option value="hots2">host2</option>
</select>
I don't understand why there is no option child if I view the source code of the setting page in text editor, while the option children appear when I view the page's DOM using Chrome developer tool. What could be the most possible reason for this? Could some content scripts in the extension change the DOM of the setting page? Also, what's the benefit to write codes like this?
Thanks!

I do this for an extension at work. I am using Javascript to load extra options in to the select. I do this because the number of options is dynamic. I don't have source available now but I can post an example later if you would like
Update
Here is an example of some javascript that might populate your select element. I am using jQuery to append the options and to iterate over my list of hosts with jQuery's each. I have two static options "Default" and "None" the the dynamic list which was generated with getHosts()
var hosts = getHosts();
if(hosts) {
var selectElement = $("#hostSelect");
selectElement.append($("<option></option>").attr("value", "0").text("-- Default Host --"));
selectElement.append($("<option></option>").attr("value", "-1").text("-- No Host Selected --"));
$.each(hosts, function(key, host) {
selectElement.append($("<option></option>").attr( "value", host.getHostID() ).text( host.getName() ));
})
}

Related

Cypress or Puppeteer: How to test page with a react select popup/popover?

Request:
Either with Cypress (preferably) or using extending Cypress with Puppeteer via cy.task(), being able to perform a test on a system-generated popup menu?
This popup menu element cannot be inspected by Chrome Devtools and is thereby not navigatable by either CSS selectors or XPath.
Details: I am using Cypress for UX testing and extend in limited cases with custom cy.task() with Puppeteer.
The web page under test has a dropdown selection that generates a popup menu, source is this npm module:
npm react-select-async-paginate
Under inspections, the popup menu is generated from an and it has these two attributes:
aria-haspopup="true"
role="combobox"
Appreciate assistance, thank you
22 Feb, Updated
This is the generated react-select-async-paginate:
<div>
<div class="***-singleValue">Offer Letter w/ Signature</div>
<div class=" css-ackcql" data-value="">
<input
id="react-select-2-input"
aria-autocomplete="list"
aria-expanded="false"
aria-haspopup="true"
aria-controls="react-select-2-listbox"
aria-owns="react-select-2-listbox"
role="combobox">
</div>
</div>
This is the attempt for selecting an option, but it does not loads selected option into <div class="***-singleValue">.
This Cypress script selects an option:
cy.get(`${selectorReactSelectPaginate}`)
.find('input[role="combobox"]')
.focus()
.type($valueSelect, { force: true })
.then(() => {
cy.wrap(true);
});
As would able to validated using this Cypress script:
cy.get(selectorReactSelectPaginate)
.find('div[class*="-singleValue"]')
.contains($valueSelectContains)
.then(() => {
cy.wrap(true);
});
Yes, the option list is tricky to get at in devtools because of the blur event (which comes from the library itself). One approach is open devtools and watch carefully as you click open the select.
Using react-select-async-paginate - Simple Example, when I click open the select I can see this div appearing and disappearing
<div id="react-select-2-listbox">
So I can use Cypress to get a look inside that
cy.get('[role="combobox"]').click()
cy.get('#react-select-2-listbox')
.then($listbox => {
console.log($listbox)
})
Now in devtools console, check out children property (has one child), then the child's children - these look like the options to be tested.
The common selector is an id starting with react-select-2-option, so I can test like so
cy.get('[role="combobox"]').click()
cy.get('#react-select-2-listbox')
.find('[id^="react-select-2-option"]') // all div's with id starting react-select-2-option
.should('have.length', 10)
.eq(3) // check out the 4th option
.invoke('text')
.should('eq', 'Option 4') // passes
Selecting an option by typing into the box
Two things affect this method of selecting
the dropdown list changes (reloads) as you type characters
the element 'div[class*="-singleValue"]' only appears after you confirm the typed value (either enter key or blur(), I'm not sure which).
This worked for me
// Type in the option
cy.get(selectorReactSelectPaginate)
.find('[role="combobox"]')
.type(valueToSelect)
// Wait for the listbox to respond
cy.get('#react-select-2-listbox')
.should('contain', valueToSelect)
// Blur or enter will set the value
cy.get(selectorReactSelectPaginate)
.find('[role="combobox"]')
.type('{enter}')
.blur()
// Check the value
cy.get(selectorReactSelectPaginate)
.find('div[class*="-singleValue"]')
.should('contain', valueToSelect)
A neat trick with test runner is to add a .wait() after the dropdown selection appears. A snapshot of the DOM will be created and you can click on the .wait() to view the snapshot and use dev tools to inspect the dropdown selection.

How can I pass a value when creating a new tab panel with CSJS

I want to create a new tabbed panel for the Dojo tab container using CSJS like:
dijit.byId('#{id:djTabContainer1}').createTab({ tabTitle: Math.random()});
The default tab panel has an panel that will use the iframe tag and I want to pass in the above call the src html attribute to the panel.
Question : I can specify a url to load in the iframe. Is there a way to pass this?
It seems like the createTab only does certain tab related parameters like action and tabTitle.
Howard
The syntax is somewhat obscure here. Starting with the code in the ExtLib demo app:
XPagesExt.nsf/Core_DynamicTabs.xsp
Change the script in button4 to:
dijit.byId('#{id:djTabContainer1}')
.createTab({
"newName":'Tab'+Math.random(),
"newHref":'/XPagesExt.nsf/page5.xsp'})
to match the syntax you're requesting.
And, in the tab that's referenced by defaultTabContent, change the title and href to use those passed URL parameters:
<xe:djTabPane xp:key="doc" id="djTabPane2"
title="${javascript:/*load-time-compute*/param.newName}"
href="${javascript:/*load-time-compute*/param.newHref}"
It will create the tab and will attempt to load the href contents. I'm not seeing it as an iframe though - it's just a container div.

How to export all relevant HTML/CSS for one element

I'm sure this question is out there but I cannot find it:
Is there a tool that can get one element of my HTML document and export that element, all its parents and all its associated CSS but nothing else?
EDIT:
Sorry I was not clear enough. I don't mean that I want Firebug/DevTools, I mean a tool [that maybe a feature of some kind of in-browser] that outputs all the relevant HTML/CSS for the selected element into a self contained file / to the clipboard.
EDIT2:
When I say outputs all relevent HTML/CSS I mean that I want that element and all it's css rules, and then each parent element with their css rules all the way up to . What I would get as an output would be enough HTML/CSS to open as a standalone page and have the target element rendered and effected by all relevant CSS rules.
Yes, there is a tool/s and ways to do that.
First, with Chrome extension, you can install SnappySnippet from Chrome Web Store. It allows easy HTML+CSS extraction from the specified (last inspected) DOM node. Additionally, you can send your code straight to CodePen or JSFiddle.
Second, CSS Used, other Chrome extension, for extracting CSS with children CSSs.
And third, without extension, if you want CSS embedded in HTML or above extensions is not working for you, you can use any Webkit based browser (like Chrome or Firefox) to run script in console which will add all css to html element and you can easily just copy OuterHTML and it will work anywhere.
var el = document.querySelector(“#yourId”); // change yourId to id of your element, or you can write “body” and it will convert all document
var els = el.getElementsByTagName("*");
for(var i = -1, l = els.length; ++i < l;){
els[i].setAttribute("style", window.getComputedStyle(els[i]).cssText);
}
So, just copy this code to Console (Right click on page->Inspect->Console), change yourid to yourid or set it to "body", run it and then right click on your element and "copy outerHTML"
Do you mean something like Firebug ( Firefox addon )? Or the Debug bar in Chrome ( Press F12 in the browser )?
In Chrome:
Press F12
Click on the loop in the bottom left.
Click on the element
Now you can see all the style.
In the big window you can see other element, and the element under
it.
In chrome, you can right click the page, and then select "inspect element" to view the html code of the page (but in the browser). Then, right click on the element that you want to export, and select "copy as html". Paste it into whatever editor you like. Hope this helps.
Press F12 or right click and go "inspect element" then select element to get the HTML code for the current webpage. Once at that point click the magnifying glass to the left and click on an element of the page using that, that will show you the code used for that specific element, after that you can right click and select "Copy Html" or you can go "Edit as Html" and then copy the code.
You can try to use a tool like Site Sucker for this. I've used it to grab entire websites, but there are settings available that might limit to what you're looking for.
Great question - it was alive and kicking for me today :-)!
Building on the accepted answer (thank you for that!) and this answer, I've got:
var el = document.querySelector("#question > div.post-layout > div.postcell.post-layout--right > div.s-prose.js-post-body"); // change yourId to id of your element, or you can write “body” and it will convert all document
var els = el.getElementsByTagName("*");
for(var i = -1, l = els.length; ++i < l;){
el = els[i]
s = getComputedStyle(el)
for (let styleKey in el.style) {
for (let computedStyleKey in s) {
let computedStyleKeyCamelCase = computedStyleKey.replace(/\-([a-z])/g, v => v[1].toUpperCase());
if ((typeof el.style[styleKey] != "function") && (styleKey != 'cssText')){
if(styleKey == computedStyleKeyCamelCase) {
el.style[styleKey] = s[computedStyleKey];
}
}
}
}
}
P.S.:
The above code should run in the Developer Tools (F12) console (tried it in Chrome) and it will add the inline style to each element
After running you could right click and do Copy / OuterHTML

When using HTML <select> tag, changed 'selected' value not displayed in Firefox

Hello (this is a copy of my post on the Seaside mailing list; first try at stackoverflow),
How do I get the rendered display of a drop-down select list to show an updated selection from another session, in Firefox? (I'm using 3.6.13)
This problem does not appear in Chrome, IE or Opera.
Here is the scenario: I have a domain object with an attribute displayed in a drop-down list. Some other session updates the attribute. I refresh my display, but the rendered selection does not change. Using Firebug, the generated html shows the updated selection. This may be basic HTML knowledge, but should the displayed value not update to show the changed 'selected' option? Or is the value intended to be set only on the initial page display and then only by a user action?
Example: I have a demo Seaside component with a class variable #testStateListSelection which is selected to 'one' in a Seaside session. If I change the value to 'three' in another Seaside session, the displayed value stays as 'one' in the original session after rendering again, even though the "selected" in the generated HTML shows "three".
renderSelectionListOn: html
html form: [
html select
list: #('one' 'two' 'three' 'four' 'five');
selected: self class testStateListSelection;
callback: [:value | self class testStateListSelection: value].
html break.
html submitButton
callback: [Transcript cr; show: self class testStateListSelection];
with: 'Save']
...the displayed value shows 'one', even though the HTML is...
<select name="1">
<option value="1">one</option>
<option value="2">two</option>
<option value="3" selected="selected">three</option>
<option value="4">four</option>
<option value="5">five</option>
</select>
How do I get the drop-down selected value to show 'three'?
BTW: all I know about HTML & browser behaviour I've learned from coding Seaside, so I may have a skewed perspective ;-)
Thanks for any help.
The problem is that, when you refresh your page, your browser is remembering which option was previously selected. This feature is designed to make it harder to lose your form data during long forms and is discussed a bit on the Mozillazine forums
Instead of refreshing the page. if you load the page "fresh" by going to the address bar and pressing return, you'll get the page loaded from the server again - with the updated select
Another cause of the problem might be that your browser tries to autocomplete the form for you based on your last submission. Make sure you have disabled this feature in the preferences of your web browser. You can also try to tell the form-tag with an unofficial attribute not to autocomplete:
html form noAutocomplete; with: [ ...
Whenever the page is refreshed the accessor self class testStateListSelection is run.
In fact the code you provide works perfectly for me. Are you sure that the accessors work as expected?
testStateListSelection
^ testStateListSelection " <-- forgetting the return is a common problem "
testStateListSelection: aString
testStateListSelection := aString
If using javascript to refresh the page...
window.location.reload();
...will NOT re-render the select elements. They will retain their dynamic values regardless of what the new source HTML says.
To force the select elements to re-render, use...
window.location.reload(true);

HTML - MOOTOOLS- Add option to select box in ie6

<select id="selectId">
<option>Please select product ...</option>
</select>
i try on firefox and it work
$('selectId').innertHTML = '<option>Test test</option>'
but on ie , it not work, how to add a option by string option like above in ie
Use the Element Class instead:
new Element('option', {
text: 'test option'
}).inject($('selectId'));​
Example: http://www.jsfiddle.net/EJH5b/
If you are going to use Mootools, then you should really use the Mootools methods rather than switch between it and vanilla Javascript. One benefit from doing this is that Mootools is already taking care of browser inconsistencies for you. Therefore, if you ignore its methods, you will have to take care of them yourself.
To access the properties of an elements the Mootools way, you can use the set and get methods on any element. The dollar ($) function returns an element so you can just chain set and get to that.
//returns selectId's HTML
var foo = $('selectId').get('html');
//Sets the HTML of selectId to <option>Test test</option>
$('selectId').set('html', '<option>Test test</option>'); //
In this case, you just need to use set.
One thing you should be aware of it is this does not add an option to a select box but instead replaces everything inside of the select box with an option. Consequently, if you wanted to use this to add multiple options to a select box, it will not work as you are resetting the HTML each time. It does not make much sense to have a select box that only has a single option so I will assume you are trying to append an option, rather than replace everything with an option. In that case, do the following:
//get the current options selectId's options
var options = $('selectId').get('html');
//Add your own option onto the end
options = options + '<option>Test test</option>';
//Set the HTML of selectId to whatever is stored in options
$('selectId').set('html', options);