Watir-WebDriver: Find elements which class is not 'completed' - watir

I have a bunch of li elements. They are either with uncompleted, 'current' or completed class or without a class.
How do I find all li elements without completed class?
So far I am doing this by selecting necessary li objects from collection of li (through calling #attribute_value('class'), but maybe there is some elegant locating strategy in Watir-WebDriver?
UPD: As long as there is some misunderstanding of the question.
I want to know if there is locating strategy within Watir-WebDriver to find elements which class is not completed.
I know I can do this with Ruby and doing it like this:
browser.lis.select do |li|
li.attribute_value('class') != 'completed'
end
But the question is if I can do this in one line by passing some argument to #lis
UPD2: Just realized that given class names narrows solutions. Updated question and sorry for that.

The LI collection supports locators, which means you can do:
browser.lis(:class, 'uncompleted').each{ |x|
puts x.text
}
UPDATE: For the case where there are multiple classes, you can modify the above to use a regex to check for not completed:
browser.lis(:class, /^(?!completed$)/).each{ |x| puts x.class_name }
This returns all li that have no class or are not exactly 'completed' (ex 'completed2').
Note: I think .class_name may have better support than attribute_value('class') (which I believe does not work in IE as it needs to be className).

In order to not assume that there are only two classes of arrays, you can do:
all = browser.lis.collect { |li| li.class }
completed = browser.lis(:class, 'completed').collect { |li| li.class }
not_completed = (all - completed)
or even:
all = browser.lis.collect { |li| li.class }
not_completed = Array.new
all.each do |li|
if li.class != "completed"
not_completed << li
end
end

Related

Building a std::map and issue with using std::emplace

Code:
std::map<CString, S_DISCUSSION_HIST_ITEM> mapHistory;
// History list is in ascending date order
for (auto& sHistItem : m_listDiscussionItemHist)
{
if (m_bFullHistoryMode)
mapHistory.emplace(sHistItem.strName, sHistItem);
else if (sHistItem.eSchool == m_eActiveSchool)
mapHistory.emplace(sHistItem.strName, sHistItem);
}
// The map is sorted by Name (so reset by date later)
// The map has the latest assignment info for each Name now
Observation:
I now understand that std::emplace behaves like this:
The insertion only takes place if no other element in the container has a key equivalent to the one being emplaced (keys in a map container are unique).
Therefore my code is flawed. What I was hoping to acheive (in pseudo code) is:
For Each History Item
Is the name in the map?
No, so add to map with sHitItem
Yes, so replace the sHistItem with this one
End Loop
By the end of this loop iteration I want to have the most recent sHitItem, for each person. But as it is, it is only adding an entry into the map if the name does not exist.
What is the simplest way to get around this?
Use insert_or_assign method if the item is assignable. It will be assigned if it already exists. Or use [] operator followed by assignment, it will default-construct item if it does not exist.
For non-assignable types I'm afraid there's no convenient way.

Sequence diagram multiple calls to same method from different locations

I want to create a sequence diagram of my program.
The code goes like this:
I have a class SFC, this class starts with the method parseScenario(). The parseScenario() method is a loop until all elements in a list are looped over. In this loop I call the parseEntryLine(e) method, where e is an entry in that list.
Now my problem occurs.
In parseEntryLine(e) there is an IF statement as follows:
if (currentGM.isBrick ()) {
animateExpr(currentGM);
//Check if it has a next
if (currentGM._next != null) { parseEntryLine (currentGM._next); }
} else {
//random code
parseEntryLine(buttonStringClicked);
}
}
How do I model this in a sequence diagram?
I managed to work until this point:
(I realize this might already be a wrong start).

Efficient way to determine if there is more than one distinct item using linq.js

I'm looking for an efficient way using linq.js to determine if a collection has more than one distinct value. I assume that the following approach is inefficient because it has to consider the entire collection.
if (Enumerable.From(collection).Distinct().Take(2).Count() > 1) {
//it's not unique, continue loop
}
My question is similar to one:
Efficient Linq Enumerable's 'Count() == 1' test
Is there a more efficient linq.js-based technique? Thanks!
If you're specifically testing to see if a collection has more than one item in it, the idiomatic way to write it (IMHO) is to use Skip in conjunction with Any. Skip the first item and if there are any others in the collection, it has more than one. If it was empty, the Skip would effectively do nothing and there still wouldn't be any other items in the collection.
In your case, your condition would be:
if (Enumerable.From(collection).Distinct().Skip(1).Any()) {
//it's not unique, continue loop
}
var test = collection[0];
if (Enumerable
.From(collection)
.Skip(1)
.Any(function (e) { return e != test; })
)
Let me explain it. At least 2 distinct items mean that for any item there is at least one item that is not equal to it. Let's pick first item, you could pick any other, just first is more convenient and let's see if there is any other number not equal to it (except itself).

Is there a way to change the text of checked/unchecked MCheckBox states?

How would I go about changing the default MCheckBox state text (currently I/0) to, for example, YES/NO or ON/OFF?
Mr. Daniel Kurka is the author for all the widget classes in MGWT. If the look & feel is not
fulfilling our requirement, We can edit those classes and rewrite them according to our requirement.Because they are open source. I done this on many classes like CellList,FormListEntry and MCheckBox. code for ON/OFF instead of I/O
public MyOwnCheckBox(CheckBoxCss css) {
this.css = css;
css.ensureInjected();
setElement(DOM.createDiv());
addStyleName(css.checkBox());
onDiv = DOM.createDiv();
onDiv.setClassName(css.on());
onDiv.setInnerText("ON");
getElement().appendChild(onDiv);
middleDiv = DOM.createDiv();
middleDiv.setClassName(css.middle());
Element middleContent = DOM.createDiv();
middleContent.setClassName(css.content());
middleDiv.appendChild(middleContent);
getElement().appendChild(middleDiv);
offDiv = DOM.createDiv();
offDiv.setClassName(css.off());
offDiv.setInnerText("OFF");
getElement().appendChild(offDiv);
addTouchHandler(new TouchHandlerImplementation());
setValue(true, false);
}
Write a new class like MyOwnCheckBox.just copy the code in MCheckBox and paste in your class MyOwnCheckBox, find and replace the MCheckBox with MyOwnCheckBox in the code(change constructor's name). do the following changes.
onDiv.setInnerText("ON");
offDiv.setInnerText("OFF");
and finally create object to MyOwnCheckBox rather MCheckBox, it'll shows MCheckBox with ON/OFF.
Right now there is no way to do that, but there is no real reasons that checkbox does not implement HasText other than we might need to update the css so that big text will not break the layout.
If you think mgwt should implement this go and vote for this issue: http://code.google.com/p/mgwt/issues/detail?id=171
Well, an easy way to accomplish the same thing, without creating a new class that mimics MCheckBox, is to do something like the code below:
CheckBoxCss css = MGWTStyle.getTheme().getMGWTClientBundle().getCheckBoxCss();
String offClass = css.off();
String onClass = css.on();
NodeList<Node> checkBoxElems;
mIsSingleSkuBox = new MCheckBox(css);
checkBoxElems = mIsSingleSkuBox.getElement().getChildNodes();
for( int i = 0; i < checkBoxElems.getLength(); i++ )
{
Element openElem = (Element) checkBoxElems.getItem(i);
String className = openElem.getClassName();
if( className.equals( offClass))
{
openElem.setInnerText("No" );
}
else if( className.equals( onClass))
{
openElem.setInnerText("Yes" );
}
}
It will probably have space problems with anything longer than 3 characters, but it works consistently with "Yes" and "No" for me.

Parallel.ForEach Ordered Execution

I am trying to execute parallel functions on a list of objects using the new C# 4.0 Parallel.ForEach function. This is a very long maintenance process. I would like to make it execute in the order of the list so that I can stop and continue execution at the previous point. How do I do this?
Here is an example. I have a list of objects: a1 to a100. This is the current order:
a1, a51, a2, a52, a3, a53...
I want this order:
a1, a2, a3, a4...
I am OK with some objects being run out of order, but as long as I can find a point in the list where I can say that all objects before this point were run. I read the parallel programming csharp whitepaper and didn't see anything about it. There isn't a setting for this in the ParallelOptions class.
Do something like this:
int current = 0;
object lockCurrent = new object();
Parallel.For(0, list.Count,
new ParallelOptions { MaxDegreeOfParallelism = MaxThreads },
(ii, loopState) => {
// So the way Parallel.For works is that it chunks the task list up with each thread getting a chunk to work on...
// e.g. [1-1,000], [1,001- 2,000], [2,001-3,000] etc...
// We have prioritized our job queue such that more important tasks come first. So we don't want the task list to be
// broken up, we want the task list to be run in roughly the same order we started with. So we ignore tha past in
// loop variable and just increment our own counter.
int thisCurrent = 0;
lock (lockCurrent) {
thisCurrent = current;
current++;
}
dothework(list[thisCurrent]);
});
You can see how when you break out of the parallel for loop you will know the last list item to be executed, assuming you let all threads finish prior to breaking. I'm not a big fan of PLINQ or LINQ. I honestly don't see how writing LINQ/PLINQ leads to maintainable source code or readability.... Parallel.For is a much better solution.
If you use Parallel.Break to terminate the loop then you are guarenteed that all indices below the returned value will have been executed. This is about as close as you can get. The example here uses For but ForEach has similar overloads.
int n = ...
var result = new double[n];
var loopResult = Parallel.For(0, n, (i, loopState) =>
{
if (/* break condition is true */)
{
loopState.Break();
return;
}
result[i] = DoWork(i);
});
if (!loopResult.IsCompleted &&
loopResult.LowestBreakIteration.HasValue)
{
Console.WriteLine("Loop encountered a break at {0}",
loopResult.LowestBreakIteration.Value);
}
In a ForEach loop, an iteration index is generated internally for each element in each partition. Execution takes place out of order but after break you know that all the iterations lower than LowestBreakIteration will have been completed.
Taken from "Parallel Programming with Microsoft .NET" http://parallelpatterns.codeplex.com/
Available on MSDN. See http://msdn.microsoft.com/en-us/library/ff963552.aspx. The section "Breaking out of loops early" covers this scenario.
See also: http://msdn.microsoft.com/en-us/library/dd460721.aspx
For anyone else who comes across this question - if you're looping over an array or list (rather than an IEnumberable ), you can use the overload of Parallel.Foreach that gives the element index to maintain original order too.
string[] MyArray; // array of stuff to do parallel tasks on
string[] ProcessedArray = new string[MyArray.Length];
Parallel.ForEach(MyArray, (ArrayItem,loopstate,ArrayElementIndex) =>
{
string ProcessedArrayItem = TaskToDo(ArrayItem);
ProcessedArray[ArrayElementIndex] = ProcessedArrayItem;
});
As an alternate suggestion, you could record which object have been run and then filter the list when you resume exection to exclude the objects which have already run.
If this needs to be persistent across application restarts, you can store the ID's of the already executed objects (I assume here the objects have some unique identifier).
For anybody looking for a simple solution, I have posted 2 extension methods (one using PLINQ and one using Parallel.ForEach) as part of an answer to the following question:
Ordered PLINQ ForAll
Not sure if question was altered as my comment seems wrong.
Here improved, basically remind that parallel jobs run in out of your control order.
ea printing 10 numbers might result in 1,4,6,7,2,3,9,0.
If you like to stop your program and continue later.
Problems alike this usually endup in batching workloads.
And have some logging of what was done.
Say if you had to check 10.000 numbers for prime or so.
You could loop in batches of size 100, and have a prime log1, log2, log3
log1= 0..99
log2=100..199
Be sure to set some marker to know if a batch job was finished.
Its a general aprouch since the question isnt that exact either.

Resources