test for popup with QUnit - qunit

I'm trying to see whether a popup is shown after a certain action. The popup is done with pnotify and puts a div.ui-pnotify in the DOM. I can see the notification popping up in the tests, but I can't seem to test it's visibility with QUnit, most probably because of a delay. Anybody here with experience in this area?
ok(find('div.ui-pnotify').length, 'Name has been changed');
Chrome console:
<div class="ui-pnotify " style="width: 300px; right: 25px; top: 25px; opacity: 1; display: block; cursor: auto;"><div class="alert ui-pnotify-container alert-success ui-pnotify-shadow" style="min-height: 16px;"><div class="ui-pnotify-icon"><span class="fa fa-check"></span></div><div class="ui-pnotify-closer" style="cursor: pointer; visibility: hidden;"><span class="fa fa-times"></span></div><div class="ui-pnotify-sticker" style="cursor: pointer; visibility: hidden;"><span class="fa fa-play"></span></div><h4 class="ui-pnotify-title">Persoonlijke gegevens</h4><div class="ui-pnotify-text">Uw persoonlijke gegevens zijn opgeslagen.</div></div></div>

I'm not familiar with find(), unless you're using this, which won't work for various reasons. However, this test works for me:
QUnit.test('example', function () {
ok($('div.ui-pnotify').length, 'Name has been changed');
});
JSFiddle

Related

Images appearing in all browsers but firefox

I have a website that displays fine in chrome but not in Firefox.
This is chrome:
This is Firefox:
Three of the four main images are missing - oddly the 4th one displays fine, despite having identical code. the inspector shows the images are downloading successfully:
I have also cleared the caches, updated Firefox, etc., to no avail.
In response to the queries:
All images are served from digital ocean, not locally.
This is the css and html for the learn image and the smile image, of which the smile image appears in FF while the learn button doesn't:
CSS
.four_box {
position: absolute;
}
.four_btn {
cursor: pointer;
transition: all .7s;
}
.four_label_anchor {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
pointer-events: none;
}
.smile_size {
height: 262px;
width: 326px;
}
.learn_size {
height: 263px;
width: 183px;
}
HTML
<div id="learn" class="learn_size four_box" style="top: 437px; left: 771px;">
<img id="learn_btn" class="learn_size four_btn" style="
background: url(/static/img/swirl_home/chalk-btn.png);"
onclick="animHome(this.id);">
<div class="learn_size four_label_anchor">
<div id="learn_label" class="four_label">Learn</div>
<button id="learn_return" class="btn_href return_btn">
return
</button>
</div>
</div>
</div>
<div id="smile" class="smile_size four_box" style="top: 438px; left: 954px;">
<img id="smile_btn" class="smile_size center four_btn" style="
background: url(/static/img/swirl_home/bird-btn.png);"
onclick="animHome(this.id); homeSnapshots();">
<div class="smile_size four_label_anchor">
<div id="smile_label" class="four_label">Smile</div>
<button id="smile_return" class="btn_href return_btn">
return
</button>
</div>
</div>
I will reread the Firefox link
If you are displaying local images, can be the problem.
Use / instead of \ in the images URL will solve the problem
Otherwise, Mozilla has a general help page for such problem : https://support.mozilla.org/en-US/kb/fix-problems-images-not-show

Reveal Image onClick

I am working on a project. How can I use Javascript to reveal a centered image when clicking inside a box without using a button?
Like this you mean? I used javascript a little, but it works!!!
<!DOCTYPE html>
<html>
<body>
<div style="background-color: red; width: 50px; height: 50px;" onclick="xSignDisplayLetter()" id="one"></div>
<br />
<div style="background-color: red; width: 50px; height: 50px;" onclick="xSignDisplayLetterVerTwo()" id="two"></div>
<br />
<div style="background-color: red; width: 50px; height: 50px;" onclick="revealImg()" id="image"></div>
<script>
function revealImg() {
document.getElementById("image").innerHTML = "<img src='https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png' alt='Image' style='width: 50px; height: 50px;' />"
}
function xSignDisplayLetter() {
document.getElementById("one").innerHTML = "<img src='https://image.freepik.com/free-icon/x-symbol_318-1407.jpg' alt='Image' style='width: 50px; height: 50px;' />"
}
function xSignDisplayLetterVerTwo() {
document.getElementById("two").innerHTML = "<img src='https://d3qdvvkm3r2z1i.cloudfront.net/media/catalog/product/cache/1/image/1800x/6b9ffbf72458f4fd2d3cb995d92e8889/n/o/nope_newthumb.png' alt='Image' style='width: 50px; height: 50px;' />"
}
</script>
</body>
</html>
If you don't know javaScript a little, then there are js tutorials all over the web.
W3Schools is a good idea for short-term tutorials that teach you a lot, and is relatively fun to mess around with.
CodeCademy is a good long-term full code tutorial that will take a few weeks to learn but helps a million via your coding skill. You will need to sign up but it's free and saves all your work (code) when you're done.
You should load the image in your HTML and hide it using a CSS class like hidden. Then you will want to use addEventListener to run a function when the image is clicked, which toggles the visibility of the image. The centering of the image can also be done using CSS.
const blocks = document.querySelectorAll('.block');
blocks.forEach((block) => {
block.addEventListener('click', () => toggleVisibility(block.querySelector('img')));
});
function toggleVisibility(el) {
el.classList.toggle('hidden');
}
.container {
display: flex;
}
.block {
background-color: red;
padding: 10px;
}
.hidden {
display: none;
}
<div class="container">
<div class="block">
<img src="https://www.placehold.it/150x150">
</div>
<div class="block">
<img src="https://www.placehold.it/150x150">
</div>
<div class="block">
<img src="https://www.placehold.it/150x150">
</div>
</div>
add an onclick attribute to your boxes that calls a function that shows a hidden image.
<div onclick="showImages()"></div>
you can add onclick listener to div and in onclick function you can change div's class
<div class="redbox" id="box" onclick="showImage()"></div>
showImage(){
var box =document.getelementbyid("box").
box.classList.remove("redbox");
box.classList.add("image");
}

capybara can not find file input field to attach file

I use ruby, cucumber and capybara.
My html looks like this:
<tr>
<th>
Promotion codes
</th><td><div class="t-zone" id="promocodesZone">
<span style="display: inline-block;">
<span class="field"><label class="field-label">File name:
<span style="text-transform: none;" class="status-ok"></span></label></span>
<span class="field"><label class="field-label">Codes available:
<span style="text-transform: none;" class="status-ok">0</span></label></span>
<span class="field"><label class="field-label">Codes used:
<span style="text-transform: none;" class="status-ok"></span></label></span>
<span class="field"><label class="field-label">Codes uploaded on:
<span style="text-transform: none;" class="status-ok"></span></label></span>
</span>
<div style="margin-bottom: 15px;"><div class="t-upload">
<div id="promocodesUpload">
<div class="qq-uploader">
<div class="qq-upload-drop-area" style="display: none;"><span>Drop </span></div>
<a class="qq-upload-button btn" style="position: relative; overflow: hidden; direction: ltr;">Upload
<input type="file" name="file" style="position: absolute; right: 0px; top: 0px; font-family: Arial; font-size: 118px; margin: 0px; padding: 0px; cursor: pointer; opacity: 0;"></a>
<ul class="qq-upload-list"></ul></div></div>
</div>
</div>
</div>
</td>
</tr>
Basically what I need to do is to upload a file by clicking on link "Upload":
<a class="qq-upload-button btn" style="position: relative; overflow: hidden; direction: ltr;">Upload<input type="file" name="file" style="position: absolute; right: 0px; top: 0px; font-family: Arial; font-size: 118px; margin: 0px; padding: 0px; cursor: pointer; opacity: 0;"></a>
But I keep failing because capybara is unable to find the necessary element...
I have tried many things already:
attach_file('//*[#id="promocodesUpload"]/div/a/input', File.absolute_path($campaign_promotional_code_path))
Result: Unable to find file field "//*[#id=\"promocodesUpload\"]/div/a/input" (Capybara::ElementNotFound)
and
within(:xpath, '//*[#id="promocodesUpload"]/div/a') do
attach_file("input", File.absolute_path($campaign_promotional_code_path))
end
Result: Unable to find file field "input" (Capybara::ElementNotFound)
and
attach_file("Upload", File.absolute_path($campaign_promotional_code_path)
Result: Unable to find file field "Upload" (Capybara::ElementNotFound)
and
click_link("Upload")
Result: Unable to find link "Upload" (Capybara::ElementNotFound)
and
Any help please? :)
Try this:
page.driver.browser.all(:xpath, '//input[#name="file"]')[0].send_keys('/home/userA/Desktop/chivalry-medieval-warfare.jpg')
or:
page.driver.browser.all(:xpath, '//input[#type="file"]').last.send_keys('/home/userA/Desktop/chivalry-medieval-warfare.jpg')
Capybara can't find the file input because it's opacity is 0, so it's hidden on the page. - Your best bet is to use execute_script to modify the file inputs style attribute so it becomes visible before calling attach_file
If you have jQuery on your web page:
page.execute_script("$('input[name=file]').css('opacity','1')")
If you don't have jQuery on your web page:
page.execute_script("document.getElementsByName('file')[0].style.opacity = 1")
As per documentation you can set make_visible option to true if the element is hidden somehow.
# will attach file to a descendant file input element that has a name, id, or label_text matching 'My File'
page.attach_file('My File', '/path/to/file.png', make_visible: true)
attach_file("user[logo]", Rails.root + "app/assets/images/image.jpeg", make_visible: true)
It is better: "In the case of the file field being hidden for styling reasons the make_visible option can be used to temporarily change the CSS of the file field, attach the file, and then revert the CSS back to original."
make_visible: true
As recommended here: https://www.rubydoc.info/gems/capybara/Capybara%2FNode%2FActions:attach_file

getHtml() function in CKEditor not performing as expected

The Project:
I am creating a prototype plugin using CKEditor v4.3.
The plugin loads an iframe of a page I have already created (in the same project). The contents inside the iframe is a necessary part of the project, thus I must use it. Once the plugin loads, I traverse the iframe & get the Body contents of the iframe. After OnOk, I perform getHtml() to get the latest contents and then insertHtml into the editor.
The problem:
The results from getHtml() (see code) is not the same as what is in the dom. The markup is getting changed and removed. All I want is to have the same markup that appears in the dom.
The Code: Here is my plugin code:
var iframeWindow = null;
var theElement = null;
CKEDITOR.plugins.add('airmath',
{
requires: 'iframedialog',
icons: 'airmath',
init: function (editor) {
var height = 480;
var width = 750;
var url = CKEDITOR.basePath + 'plugins/airmath/integration/airmath.html';
CKEDITOR.dialog.addIframe(
'myiframedialogDialog',
'Math Editor',
url, width, height,
function () {
theElement = this.getElement();
iframeWindow = theElement.getFrameDocument().getBody();
},
{
onOk: function () {
editor.insertHtml(iframeWindow.getHtml());
}
}
);
editor.addCommand('myiframedialog', new CKEDITOR.dialogCommand('myiframedialogDialog'));
editor.ui.addButton('AirMath',
{
label: 'Math Editor',
command: 'myiframedialog',
toolbar: 'insert'
});
}
});
The dom:
This is the dom from chrome developer tools:
<span class="MathJax" id="Eq-Editor-Eq-Container-1-1-Frame" role="textbox" aria-readonly="true" style="">
<nobr>
<span class="math" id="MathJax-Span-1" style="width: 15.642em; display: inline-block;">
<span style="display: inline-block; position: relative; width: 7.933em; height: 0px; font-size: 197%;">
<span style="position: absolute; clip: rect(1.461em 1000.002em 2.667em -0.22em); top: -2.314em; left: 0.002em;">
<span class="mrow" id="MathJax-Span-2">
<span class="mstyle" id="MathJax-Span-3">
<span class="mrow" id="MathJax-Span-4">
<span class="texatom" id="MathJax-Span-5">
<span class="mrow" id="MathJax-Span-6">
<span class="mi" id="MathJax-Span-7" style="font-family: MathJax_Math; font-style: italic;">f
<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.065em;">
</span>
</span>
<span class="mfenced" id="MathJax-Span-8">
<span class="mo" id="MathJax-Span-10" style="">
<span style="font-family: MathJax_Main;">(</span>
</span>
<span class="texatom" id="MathJax-Span-11">
<span class="mrow" id="MathJax-Span-12">
<span class="mi" id="MathJax-Span-13" style="font-family: MathJax_Math; font-style: italic;">x</span>
</span>
</span>
<span class="mo" id="MathJax-Span-14" style="">
<span style="font-family: MathJax_Main;">)</span>
</span>
</span>
<span class="mo" id="MathJax-Span-15" style="font-family: MathJax_Main; padding-left: 0.287em;">=</span>
<span class="mn" id="MathJax-Span-16" style="font-family: MathJax_Main; padding-left: 0.287em;">5</span>
<span class="mn" id="MathJax-Span-17" style="font-family: MathJax_Main;">0</span>
<span class="mn" id="MathJax-Span-18" style="font-family: MathJax_Main;">0</span>
<span class="mo" id="MathJax-Span-19" style="font-family: MathJax_Main; padding-left: 0.224em;">×</span>
<span class="mn" id="MathJax-Span-20" style="font-family: MathJax_Main; padding-left: 0.224em;">1</span>
<span class="mo" id="MathJax-Span-21" style="font-family: MathJax_Main;">.</span>
<span class="msup" id="MathJax-Span-22" style="padding-left: 0.16em;">
<span style="display: inline-block; position: relative; width: 0.985em; height: 0px;">
<span style="position: absolute; clip: rect(1.429em 1000.002em 2.286em -0.22em); top: -2.188em; left: 0.002em;">
<span class="mn" id="MathJax-Span-23" style="font-family: MathJax_Main;">2</span>
<span style="display: inline-block; width: 0px; height: 2.191em;">
</span>
</span>
<span style="position: absolute; top: -2.156em; left: 0.509em;">
<span class="mi" id="MathJax-Span-24" style="font-size: 70.7%; font-family: MathJax_Math; font-style: italic;">x</span><span style="display: inline-block; width: 0px; height: 1.747em;">
</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>
<span style="display: inline-block; width: 0px; height: 2.318em;">
</span>
</span>
</span>
<span style="border-left-width: 0.003em; border-left-style: solid; display: inline-block; overflow: hidden; width: 0px; height: 2.128em; vertical-align: -0.559em;">
</span>
</span>
</nobr>
</span>
<script id="Eq-Editor-Eq-Container-1-1" type="math/mml"><math xmlns="http://www.w3.org/1998/Math/MathML">
<mstyle displaystyle="true">
<mrow class="MJX-TeXAtom-ORD">
<mi>f</mi>
<mfenced open="(" close=")">
<mrow class="MJX-TeXAtom-ORD">
<mi>x</mi>
</mrow>
</mfenced><mo>=</mo>
<mn>5</mn>
<mn>0</mn><mn>0</mn>
<mo>×<!-- × --></mo>
<mn>1</mn>
<mo>.</mo>
<msup>
<mn>2</mn>
<mi>x</mi>
</msup>
</mrow></mstyle>
</math>
</script>
<input type="text" class="hidden" id="Eq-Container-1_input_Eq-Editor-Eq-Container-1-1" name="Eq-Container-1_input_Eq-Editor-Eq-Container-1-1">
The Results:
And this is what I get in the ckEditor window after clicking "Ok" from the dialog window. Viewing in Source mode:
<div class="mje_editor_row" id="Eq-Editor-Eq-Container-1-1-Row">
<span style="font-size:197%">
<em>f</em>
<span style="font-family:mathjax_main">(</span>
<em>x</em>
<span style="font-family:mathjax_main">)</span>
<span style="font-family:mathjax_main">=</span>
<span style="font-family:mathjax_main">5</span>
<span style="font-family:mathjax_main">0</span>
<span style="font-family:mathjax_main">0</span>
<span style="font-family:mathjax_main">×</span>
<span style="font-family:mathjax_main">1</span>
<span style="font-family:mathjax_main">.</span>
<span style="font-family:mathjax_main">2</span>
<em>x</em>
</span>
<input name="Eq-Container-1_input_Eq-Editor-Eq-Container-1-1" type="text" />
What I've done:
Thinking that there could be a timing issue with my iframe page loading, I tried an alert(iframeWindow.getHtml()); at the bottom of the addIframe function(). I was surprised when it gave me exactly the data as shown in the dom. It was just what I wanted. Also, as a further note, (as a user) I did not make any changes to the iframe data once the dialog loaded. I just clicked Ok after waiting for a couple seconds to see that the page is fully loaded. I have poured through http://ckeditor.com/forums for hints I have reviewed http://stackoverflow.com for help. So far the problem eludes me. I haven't found anything-- although it is probably one of those things staring right at me in the face.
If any of you have experience with this issue, I would love to hear how to solve it. Many thanks!
Success is so sweet when you find the answer you have been looking for! I am new to CKEditor plugin programming - so I just didn't know. It has been a rough road. But I got it. Here is the details.
CKEditor came out with this new layer called ACF (Advanced Content Filtering) in version 4.1. Because I wasn't aren't aware of this extra layer, my HTML tags got stripped out when my plugin sent HTML data to the ckEditor window on editor.insertHtml. After I added allowedContent: true to the plugin code (see below), my HTML is no longer stripped out. No more filtering!
Details about allowing specific tags described here.
And finally, here it mentions about adding config.allowedContent = true to disable content filtering -- which I assumed was something to do in the config.js file, but changing the config.js file in this manner didn't have an effect for me.
Here is a copy of the new changed code:
var iframeWindow = null;
var theElement = null;
var height = 480;
var width = 750;
var url = CKEDITOR.basePath + 'plugins/airmath/integration/airmath.html';
CKEDITOR.plugins.add('airmath',
{
requires: 'iframedialog',
icons: 'airmath',
init: function (editor) {
allowedContent: true,
CKEDITOR.dialog.addIframe(
'myiframedialogDialog',
'Math Editor',
url, width, height,
function () {
theElement = this.getElement();
iframeWindow = theElement.getFrameDocument().getBody();
},
{
onOk: function () {
editor.insertHtml(iframeWindow.getHtml());
}
}
);
editor.addCommand('myiframedialog', new CKEDITOR.dialogCommand('myiframedialogDialog'));
editor.ui.addButton('AirMath',
{
label: 'Math Editor',
command: 'myiframedialog',
toolbar: 'insert'
});
}
});

how to click on strange select list element?

I have a problem selecting the options in unidentified dropdown menu. Elements of the dropdown appears when i click on dropdown arrow, but I cant click on them, because I don't know their id's or other properties that I can use.
Here is the code. I can't select from select_list with:
on_page(RegistrationPage).id_of_select_list_with_options = "8"
or
#browser.select_list(:name => "field_profile_bday[0][value][day]").select("8")
or
#browser.select_list(:id => "edit-field-profile-bday-0-value-day").select("8")
The error is: Element is not currently visible and so may not be interacted with (Selenium::WebDriver::Error::ElementNotVisibleError)
When I click on combo-button element dropdown list appears, but I can't select elements in it because they appear in combo-selected div after selecting. (Like "Jour" text in combo-selected div, it is there by default)
Here is the html:
<div class="form-item" id="edit-field-profile-bday-0-value-day-wrapper">
<label for="edit-field-profile-bday-0-value-day">Jour : <span class="form-required" title="Ce champ est obligatoire.">*</span></label>
<select name="field_profile_bday[0][value][day]" class="form-select required date-day" id="edit-field-profile-bday-0-value-day" ><option value="" selected="selected">Jour</option><option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4">4</option><option value="5">5</option><option value="6">6</option><option value="7">7</option><option value="8">8</option><option value="9">9</option><option value="10">10</option><option value="11">11</option><option value="12">12</option><option value="13">13</option><option value="14">14</option><option value="15">15</option><option value="16">16</option><option value="17">17</option><option value="18">18</option><option value="19">19</option><option value="20">20</option><option value="21">21</option><option value="22">22</option><option value="23">23</option><option value="24">24</option><option value="25">25</option><option value="26">26</option><option value="27">27</option><option value="28">28</option><option value="29">29</option><option value="30">30</option><option value="31">31</option></select>
</div>
<div class="combo-wrapper" style="display: inline-block; width: 61px; height: 24px; " tabindex="0"><div class="combo-button" style="width: 24px; height: 24px; display: inline-block; ">+</div><div class="combo-selected" style="width: 37px; height: 24px; display: inline-block; ">Jour</div></div>
<div class="combo-button" style="width: 24px; height: 24px; display: inline-block; ">+</div>
<div class="combo-selected" style="width: 37px; height: 24px; display: inline-block; ">Jour</div>
"Jour"
</div>
Instead of .select("8"). Try something like:
#browser.select_list(:name => "field_profile_bday[0][value][day]").option(:value, '8').select
or
#browser.select_list(:name => "field_profile_bday[0][value][day]").options[7].select
I think you needed to point to the option element and then use inherent select method. Hope this works. Good Luck!

Resources