Search with different value in array each time - e2e-testing

i need guide or help for how to search with different value 'airport' each time ‘values that define in array ‘ instead of type it hardcoded,
thanks in advance and i hope to find answer to use it in incoming scripts
it('select the origin Airport', function () {
for (let i in ['DXB dubai', 'AUH Abu Dhabi', 'JED Jeddah'])
// select the oragain
cy.get('[id="flights-search-origin-1"]')
.type('DXB dubai', {force: true}).should('have.value’,’one of the array's values ')````

I would use Array.prototype.map:
it('select the origin Airport', () => {
['DXB dubai', 'AUH Abu Dhabi', 'JED Jeddah'].map(airport => {
cy
.get('[id="flights-search-origin-1"]')
.clear().type(airport)
.should('have.value', airport);
})
})
Edit:
I've added a .clear before .type, and an assertion with the same value you've asked to type. Keep in mind this isn't an incredibly useful test, but it's what you've asked for.

Related

Change date format in dialogflow

I`m currently trying to build up a chatbot/agent with dialogflow and have honestly no knowledge about anything in the programming business/IT stuff. I´m a student who had a guestlecture where we were shown how to create Chatbots haha. But I was interested and sat down and tried to create one for my work. A simple bot that tells the customer about the opening times and gives out some information to save us some phone calls. So far so good. I want to include the function to book a table and my problem is the following:
I´ve read many questions about changing the date and time format to receive a format like "4pm on Thursday" instead of "2020-12-26T16:00:00+01:00".
So as I said I have no clue so far how the change the code to get a different output so my question would be if you could tell me where exactly I have to do that or where I can find a solution for that. Don´t get me wrong I´d love to know how to do it so yeah I´d be so happy if you could save that christmas present :)
Best regards
Mo
So, your question is vague and lacks details.
If you want to convert "2020-12-26T16:00:00+01:00" to "4pm on Thursday" in your local time here are helper functions to achieve that:
function convertParametersDateTime(date, time){
return new Date(Date.parse(date.split('T')[0] + 'T' + time.split('T')[1].split('+')[0]));
}
// A helper function that adds the integer value of 'hoursToAdd' to the Date instance 'dateObj' and return a new Data instance.
function addHours(dateObj, hoursToAdd){
return new Date(new Date(dateObj).setHours(dateObj.getHours() + hoursToAdd));
}
// A helper funciton that converts the Date instance 'dateObj' into a string that represents this time in English.
function getLocaleTimeString(dateObj){
return dateObj.toLocaleTimeString('en-US', {hour: 'numeric', hour12: true});
}
// A helper dunction that converts the Date instance 'dateObj' into a string that represents this date in English
function getLocaleDateString(dateObj){
return dateObj.toLocaleDateString('en-US', {weekday: 'long', month: 'long', day: 'numeric'});
}
Those are the helper functions. You have to call them inside the Fulfillment function for your intent. Here's a very simple example:
function makeAppointment (agent) {
// Use the Dialogflow's date and time parameters to create Javascript Date instances, 'dateTimeStart' and 'dateTimeEnd',
// which are used to specify the appointment's time.
const dateTimeStart = convertParametersDateTime(agent.parameters.date, agent.parameters.time);
const dateTimeEnd = addHours(dateTimeStart, appointmentDuration);
const appointmentTimeString = getLocaleTimeString(dateTimeStart);
const appointmentDateString = getLocaleDateString(dateTimeStart);
agent.add(`Here's the summary of your reservation:\nDate&Time: ${appointmentDateString} at ${appointmentTimeString}`);
}
The codes might include some syntax errors. Those functions give what you are looking for but you would have to adjust them according to your needs.

PDFTron: What is the proper way to find date fields in a PDF form

[PdfTron 5.2]
I have a PDF form with text and date fields. I want to find the date fields.
I can get the actions of the field with getActions().
field.getActions()
returns
{"F":[{"yc":"JavaScript","Gt":"AFDate_FormatEx(\"dd.mm.yyyy\");"}],
"K":[{"yc":"JavaScript","Gt":"...);","ey":null}]}
As you can see, the date is in actions.F[0].Gt. But checking actions.F[0].Gt
for "AFDate" seems wrong, that's too low-level.
Is there a better API function to find out, that I have a date field?
Thank you.
You are correct. The Gt property is obfuscated and minified which is volatile and not meant to be used. If you require an API, you should refer to our documentation. Everything should be available there except a few (one of which will be used below), but feel free to contact us if you do need help!
Unfortunately, there is no API currently to get that type. From my limited understanding, the "type" of a field is determined by the attached actions and not simply a specific type or flag. This suggests all fields are just text fields with special formatting actions to make it look and feel like its a date or numeric field.
In this case, you will have to check the formatting action (F) as you have already noticed for the date formatting function (AFDate_FormatEx). To get the JavaScript from that action, you should use the javascript property on the action which was not in the documentation. However, you can see it if you console log the action.
Here is an example:
const dateActionJs = /.+:"AFDate_FormatEx\(.*/;
instance.docViewer.on('annotationsLoaded', () => {
const annotations = annotManager.getAnnotationsList();
annotations.forEach(annot => {
const actions = annot.getField().getActions();
if (actions.F && actions.F[0] && actions.F[0].javascript && dateActionJs.test(actions.F[0].javascript)) { // F = Format Action
console.log('Found Date');
}
});
});
Let me know if this helps!
EDIT: You can search for AFDate instead of AFDate_FormatEx which will be sufficient.

How to Remove the addPreSearch Filter

I am trying to remove the PreSearch filer and my code is as below. How can I achieve the same?
Xrm.Page.getControl("productid").removePreSearch(function () {
Object
});
Xrm.Page.getControl("productid").addPreSearch(function () {
fetchxml2();
});
function fetchxml2() {
var fetchXml1 = "<filter type='and'>"
fetchXml1 += "<condition attribute='productid' operator='in' >";
for (var i = 0; i < Itemid.length; i++) {
fetchXml1 += "<value>" + Itemid[i] + "</value>";
}
fetchXml1 += "</condition>";
fetchXml1 += "</filter>";
Xrm.Page.getControl("productid").addCustomFilter(fetchXml1);
//Xrm.Page.getControl("productid").removePreSearch(fetchXml1);
};
In order to be able to remove the handler via removePreSearch, avoid using an anonymous function by creating a named function and using that in both addPreSearch and removePreSearch:
function preSearchHandler(){
fetchxml2();
}
Xrm.Page.getControl("productid").removePreSearch(preSearchHandler);
Xrm.Page.getControl("productid").addPreSearch(preSearchHandler);
Just wanted to add this to the discussion:
If you, say, have three different custom filters on a lookup field, the functionality will stack when you apply a new filter.
For example, if you have an option set that calls addPreSearch() on the field, if you select all three different options, you will have all three filters applied to the field simultaneously.
say the option set has three options of [option A, option B, option C],
the corresponding functions are, for simplicity [filterA, filterB, filterC],
on the change event of the option set, for each filter that you apply, simply remove the other two (in this case).
if (optionSet == 810500000) {//option A
Xrm.Page.getControl('lookup').addPreSearch(filterA);
Xrm.Page.getControl('lookup').removePreSearch(filterB);
Xrm.Page.getControl('lookup').removePreSearch(filterC);
}
else if (optionSet == 810500001) {//option B
Xrm.Page.getControl('lookup').addPreSearch(filterB);
Xrm.Page.getControl('lookup').removePreSearch(filterA);
Xrm.Page.getControl('lookup').removePreSearch(filterC);
}//so on and so forth
I hope this helps someone out, I was able to apply custom filters to a lookup based on four distinct selections and remove the "stackable" filters by addition and removal in this manner. It's a little ugly, but, hey, it works. At the end of the day, sometimes the most elegant solution is to just win, win win win win.
If you need more context (fetchXml) and such, I can post that, too...but it doesn't really go along with the point I was trying to make. These filters can be applied simultaneously! That's the main idea I wanted to convey here.

Can't listen to ItemChanged, ItemsAdded or ItemsRemoved on ReactiveList<T>

I have a ReactiveObject with a Property "A" of type "ReactiveList".
In my ViewModel I'd like to sum a property of "T" of every item in my list.
I got it working, while "A" not changes its value.
But all gets "out of sync", when I assign a new value to "A" (e.g. this.A = new ReactiveList();).
Does anyone have an idea how to solve this? I hope I explained my problem clear enough.
Instead of listening to A directly, listen to this:
this.WhenAnyObservable(x => x.A.ItemsChanged).Subscribe(...);
Whenever A changes, you'll resubscribe to A. Now, knowing when to reset to do a Sum, that's a bit more tricky. Here's the lazy yet more fool-proof way to do this:
Observable.Merge(
this.WhenAny(x => x.A, _ => Unit.Default),
this.WhenAnyObservable(x => x.Changed).Select(_ => Unit.Default))
.Select(_ => this.A.Sum(x => x.SomePropOnTheItem))
.DistinctUntilChanged()
.Subscribe(x => Console.WriteLine("Latest sum is {0}", x);
1 - I'd avoid assigning new Collections continuously as part of your logic, and rather use Clear(). Which should have the same impact in terms of GC.
2- If absolutely necessary, utilize a SerialDisposable and subsribe on the main object A
this.ObservableForProperty(p=> p.A).Subscribe(newAvalue=>{
someSerialDisposable.Disposable=
newAvalue.Changed.Subscribe(_=>this.Result=this.A.Sum(x=>x.T))
});
This would dispose previous deep subscriptions on A instances.

How to maintain counters with LinqToObjects?

I have the following c# code:
private XElement BuildXmlBlob(string id, Part part, out int counter)
{
// return some unique xml particular to the parameters passed
// remember to increment the counter also before returning.
}
Which is called by:
var counter = 0;
result.AddRange(from rec in listOfRecordings
from par in rec.Parts
let id = GetId("mods", rec.CKey + par.UniqueId)
select BuildXmlBlob(id, par, counter));
Above code samples are symbolic of what I am trying to achieve.
According to the Eric Lippert, the out keyword and linq does not mix. OK fair enough but can someone help me refactor the above so it does work? A colleague at work mentioned accumulator and aggregate functions but I am novice to Linq and my google searches were bearing any real fruit so I thought I would ask here :).
To Clarify:
I am counting the number of parts I might have which could be any number of them each time the code is called. So every time the BuildXmlBlob() method is called, the resulting xml produced will have a unique element in there denoting the 'partNumber'.
So if the counter is currently on 7, that means we are processing 7th part so far!! That means XML returned from BuildXmlBlob() will have the counter value embedded in there somewhere. That's why I need it somehow to be passed and incremented every time the BuildXmlBlob() is called per run through.
If you want to keep this purely in LINQ and you need to maintain a running count for use within your queries, the cleanest way to do so would be to make use of the Select() overloads that includes the index in the query to get the current index.
In this case, it would be cleaner to do a query which collects the inputs first, then use the overload to do the projection.
var inputs =
from recording in listOfRecordings
from part in recording.Parts
select new
{
Id = GetId("mods", recording.CKey + part.UniqueId),
Part = part,
};
result.AddRange(inputs.Select((x, i) => BuildXmlBlob(x.Id, x.Part, i)));
Then you wouldn't need to use the out/ref parameter.
XElement BuildXmlBlob(string id, Part part, int counter)
{
// implementation
}
Below is what I managed to figure out on my own:.
result.AddRange(listOfRecordings.SelectMany(rec => rec.Parts, (rec, par) => new {rec, par})
.Select(#t => new
{
#t,
Id = GetStructMapItemId("mods", #t.rec.CKey + #t.par.UniqueId)
})
.Select((#t, i) => BuildPartsDmdSec(#t.Id, #t.#t.par, i)));
I used resharper to convert it into a method chain which constructed the basics for what I needed and then i simply tacked on the select statement right at the end.

Resources