Using multi-select css' select patterns in Angular By.css doesn't give multiple elements - angular-test

In css, I could do a[href^="https"] which Selects every <a> element whose href attribute value begins with "https". How can I specify same rule in By.css in Angular?
By.css is defined in https://angular.io/api/platform-browser/By as
static css(selector: string): Predicate<DebugElement>
My Angular code has several divs with id attribute equal to thumbnail-1, thumbnail-2. I want to get all of them in my Jasmine unit test.
At the moment, I am collecting them individually
let imageThumbnailDiv1 = fixture.debugElement.query(By.css("#thumbnail-1"));
let imageThumbnailDiv2 = fixture.debugElement.query(By.css("#thumbnail-2"));
If I use the multi-select pattern, I get only the 1st element. Is there a way to get multiple elements.
fit('select all thumbnails',(done)=>{
let newPracticeQuestionComponent = component;
let imageThumbnailDivs = fixture.debugElement.query(By.css("div[id^=\"thumbnail\"]"));
console.log("thumbnail divs before file upload ",imageThumbnailDivs);
expect(imageThumbnailDivs).toBeFalsy();
let file1 = new File(["foo1"], "foo1.txt");
let file2 = new File(["foo2"], "foo2.txt");
let file3 = new File(["foo3"], "foo3.txt");
//let file4 = new File(["foo4"], "foo4.txt");
let reader1 = newPracticeQuestionComponent.handleFileSelect([file1]);
let reader2 = newPracticeQuestionComponent.handleFileSelect([file2]);
let reader3 = newPracticeQuestionComponent.handleFileSelect([file3]);
setTimeout(function() {
console.log("in timeout");
fixture.detectChanges();//without this, the view will not be updated with model
let imageThumbnailDivsAfter = fixture.debugElement.query(By.css("div[id^=\"thumbnail\""));
console.log("thumbnail divs after file upload ",imageThumbnailDivsAfter); //<-- this shows only the 1st element
expect(imageThumbnailDivsAfter).toBeTruthy();
//console.log("before done call")
done();//without done, jasmine will finish this test spec without checking the assertions in the timeout
//console.log("after timeout call")
}, 2000);
});

You can use debugElement.queryAll instead of debugElement.query to get an array over which you can iterate.
let thumbnails = fixture.debugElement.queryAll(By.css(".thumbnail"));
thumbnails.forEach((debugElement)=>{
expect(debugElement)//Whatever you want to test
})

Related

How to get all <a> tag under the <div> in testcafe

In selenium query for selector, if my selector value was (#div-id a). It return all a tags.
Does in testcafe is it posible this to selector function? i just want to avoid looping to get all a tags.
Code Sample
const element = selector('#div-id').find()
var get = await brandUrls.hasAttribute();
console.log(get);
Actual element attached
Yes, it is also possible to achieve the desired behavior with TestCafè in a similar way:
import { Selector } from "testcafe";
// one option
const firstLinkSelector = Selector("#directoryLink-1 a");
// another option
const secondLinkSelector = Selector("#directoryLink-1").find("a");
Read more about the find()-method here.

How can I to empty the content of html tag?

Hello I am loading a few of data each API call, inside a tag, but when I do the second call this data is appended to the data of the previous call.
The question is how can I clear the content of a div?
I am using this for select that div
this.$refs.data
In order to add contet I am using the following code:
responseJSON.forEach(element => {
let card = Vue.extend(card)
let instance = new card({
propsData: {
ch: element
}
})
instance.$mount()
this.$refs.aaa.appendChild(instance.$el)
this.cards.push(instance)
});
Before running the responseJSON.forEach, you can clear everything in the div first by running
this.$refs.data.innerHTML = ""

JavaScript Protractor (Selenium) verify if input is focused

I'm trying to to test whether an element is focused using selenium webdriver in protractor. This is before AngularJS is loaded so I am having to use the driver as seen here:
var ptor = protractor.getInstance(),
driver = ptor.driver;
I also need to know how to make the test wait until the input is focused. I have to wait until a model is fired so the input is not focused for half a second as seen here:
window.setTimeout(function(){
$("input#email").focus();
}, 500);
Any idea how to verify if an input has focus after 500ms?
Based on my answer to this question, and adapting it to your case, it would look like:
it('should focus on foo input', function () {
// to wait 500ms+
browser.driver.sleep(600);
// using the Protractor 'element' helper
// https://github.com/angular/protractor/blob/master/docs/api.md#element
// var input = element(by.id('foo'));
// using findElement with protractor instance
var input = driver.findElement(protractor.By.id('foo'));
expect(input.getAttribute('id')).toEqual(browser.driver.switchTo().activeElement().getAttribute('id'));
});
I used glepretre's answer, but had to resolve the getAttribute promises for both elements using promise.all
let activeElement = browser.driver.switchTo().activeElement().getAttribute('id');
let compareElement = element(by.id('your-element-id')).getAttribute('id');
webdriver.promise.all([compareElement, activeElement]).then((id) => {
expect(id[0]).to.equal(id[1]);
});

Google Script - Adding dynamic parameters to href from handler

I have a Google Script published as a web app which uses UI service to display an interface with several listboxes. I can get at the values selected thru server handlers.
My problem is that I need to add these values to a url in a anchor defined in my doGet routine. (I am calling a JotForm url, and need the dynamic parameters to pre-populate the form)
I can't see how to modify the anchor from the handler function, or any other way to invoke the url I build in code.
When you want to modify any widget in a Ui created with UiApp, each widget must have an ID that you can use to getElementById() and manipulate the way you want just as if you were in the doGet function.
Here is a simple example to illustrate : (online here)
function doGet(){
var app = UiApp.createApplication().setTitle('test');
var serieNames = [' serie A',' serie B',' serie C'];
var panel = app.createVerticalPanel().setStyleAttribute('padding','30px');
var namesHandler = app.createServerHandler('showPilots').addCallbackElement(panel);
for(var n in serieNames){
var serieSelect = app.createRadioButton('pilotSelect',serieNames[n]).setId('s'+n).addClickHandler(namesHandler)
panel.add(serieSelect);
}
app.add(panel);
return app;
}
function showPilots(e){
Logger.log(JSON.stringify(e));// you can see the source parameter in e that returns the widgets ID of the button you clicked to call the handler
var app = UiApp.getActiveApplication();
var serie = e.parameter.source; // get the ID
app.add(app.createLabel('you clicked '+e.parameter.source));// then get this widget by its ID and modify it
app.getElementById(serie).setText('Clicked');// modify it
return app;// update Ui
}
EDIT : here is a version that manipulates anchors, it is perfectly possible to change the url from a handler.
test here
code :
function doGet(){
var app = UiApp.createApplication().setTitle('test');
var links = ['link 1',' link 2',' link 3'];
var linkshref = ['http://www.google.com','http://www.packtpub.com/google-apps-script-for-beginners/book','http://stackoverflow.com/questions/tagged/google-apps-script'];
var panel = app.createVerticalPanel().setStyleAttribute('padding','30px');
var namesHandler = app.createServerHandler('changeUrl').addCallbackElement(panel);
for(var n in links){
var linkWidget = app.createAnchor(links[n], linkshref[n]).setId('s'+n);
panel.add(linkWidget);
}
var btn = app.createButton('change links',namesHandler);
app.add(panel.add(btn));
return app;
}
function changeUrl(e){
Logger.log(JSON.stringify(e));// you can see the source parameter in e that returns the widgets ID of the button you clicked to call the handler
var app = UiApp.getActiveApplication();
var links = ['New link 1','New link 2','new link 3'];
var linkshref = ['http://www.microsoft.com','http://www.w3schools.com/js/','https://sites.google.com/site/appsscriptexperiments/'];
for(var n in links){
app.getElementById('s'+n).setHref(linkshref[n]).setHTML(links[n]);
}
return app;// update Ui
}

Simple store connected list for dojo

Is there a simpler list type than DataGrid that can be connected to a store for Dojo?
I would like the data abstraction of the store, but I don't need the header and cell stucture. I would like to be more flexible in the representation of the datalines, where maybe each line calls an function to get laid out...
You ask a really good question. I actually have a blog post that is still in draft form called "The DataGrid should not be your first option".
I have done a couple thing using the store to display data from a store in a repeated form.
I have manually built an html table using dom-construct and for each.
var table = dojo.create('table', {}, parentNode);
var tbody = dojo.create('tbody', {}, table); // a version of IE needs this or it won't render the table
store.fetch({ // this is a dojo.data.ItemFileReadStore, but you cana dapt to the dojo.Store API
query: {},
onComplete: function(itms) {
dojo.forEach(itms, function(itm, idx) {
var tr = dojo.create('tr', {}, tbody);
// use idx to set odd/even css class
// create tds and the data that goes in them
});
}
});
I have also created a repeater, where I have an html template in a string form and use that to instantiate html for each row.
var htmlTemplate = '<div>${name}</div>'; // assumes name is in the data item
store.fetch({ // this is a dojo.data.ItemFileReadStore, but you cana dapt to the dojo.Store API
query: {},
onComplete: function(itms) {
dojo.forEach(itms, function(itm, idx) {
var expandedHtml = dojo.replace(htmlTemplate, itm);
// use dojo.place to put the html where you want it
});
}
});
You could also have a widget that you instantiate for each item.