Wait for a select_list to exist and then select a value - page-object-gem

I am trying to select an option from a select list using page-object. I am using IE8(have to) which is very slow when interacting with page-object.
When /^the user selects the Test Region "([^"]*)"$/ do |regionname|
on_page(MyTestRegion) do |page|
page.region = /#{regionname}/ if regionname != "" && regionname != {}
end
end
I get Watir::Exception::UnknownObjectException: unable to locate element error.
I need to wait for the select_list element to load and then select a value.
I did try visible?, wait_until, wait_when_present, when_present but nothing so far seem to work... Is there an alternate way to wait until a element is loaded?

Related

Sending info to database and retrieving as well as using for k,v, in pairs() do

Issue i have come across is i have an item, if you use this item it writes to the database with your id and the item name. which is correct and this is what i want to happen, but i want it to first look at the database and see if the item is already there and if so stop the insert.
This is the item.
QBCore.Functions.CreateUseableItem("pumpshotgun_bp", function(source, item)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player.Functions.GetItemBySlot(item.slot) ~= nil then
QBCore.Functions.TriggerCallback('sin-crafting:server:getCrafts', src, function(result)
if result ~= nil then
TriggerClientEvent("sin-crafting:client:Update", source, "pumpshotgun_bp")
end
end)
end
end)
after that i query the info to the database
QBCore.Functions.CreateCallback('sin-crafting:server:getCrafts', function(source, cb)
local Player = QBCore.Functions.GetPlayer(source)
local cid = Player.PlayerData.citizenid
local printList = {}
MySQL.query('SELECT * FROM player_crafts WHERE cid = ?', { Player.PlayerData.citizenid }, function(crafts, item)
for k, v in pairs(crafts) do
if v == nil then
end
table.insert(printList,
{
citizenid = v.citizenid,
blueprint = v.blueprint,
}
)
end
cb(json.encode(printList))
end)
end)
and then
the item then triggers this when used and changed info from the item_bp to the actual name for the database
RegisterNetEvent('sin-crafting:client:Update', function(data)
if data == "pumpshotgun_bp" then
TriggerServerEvent('sin-crafting:server:newBlueprint', 'pumpshotgun')
end
end)
Problem now is when i use that item again it will write it again to the database and i dont want that i want instead to set up a notify script that will tell them they have already learned that.
This is the first half of my issue, the second half is pulling the list from the database and and checking it in the script. I really need help as I have been trying to do this for over a week now and cant find a way to do it
This is the config to use for the for k,v in pairs() do, <---which I cant figure out how to do right....
Config.Weapons = {
"pumpshotgun",
"dbshotgun",
"assaultrifle",
"smg",
"combatpistol",
"gusenberg",
"microsmg",
"carbinerifle",
"compactrifle",
"heavypistol",
"machinepistol",
"revolver",
"rifle_silencer",
"pistol_silencer",
"smg_silencer",
"shotgun_silencer",
"weapon_optics",
}

Adding Html tag into the title of the Tree query in Oracle APEX

I have a requirement to make few text in the title of my tree query in Oracle APEX to bold by adding b tag. But when i do that, the tag is displayed at the front end. My query is as mentioned below. I do not want to see the b tag, rather i want the text enclosed by b tag to be bold. Please help.
SELECT
CASE
WHEN CONNECT_BY_ISLEAF = 1 THEN 0
WHEN level = 1 THEN 1
ELSE -1
END
AS status,
level,
CASE
WHEN level = 1 THEN questions
ELSE '<b>' -- Comes in the front end which i do not want
|| flow_condition
|| '</b>'
|| ' - '
|| questions
END
AS title,
NULL AS icon,
question_id AS value,
NULL AS tooltip,
--null as link
apex_page.get_url(
p_page => 401,
p_items => 'P401_QUESTION_ID',
p_values => question_id,
p_clear_cache => 401
) AS link
FROM
(
SELECT
mmq.*,
mmm.flow_condition
FROM
msd_mc_questions mmq
LEFT OUTER JOIN msd_mc_par_chld_mapping mmm ON (
mmq.parent_id = mmm.parent_question_id
AND
mmq.question_id = mmm.child_question_id
)
)
START WITH
parent_id IS NULL
CONNECT BY
PRIOR question_id = parent_id
ORDER SIBLINGS BY questions
Struggled with this for hours but then found a solution via jQuery. Create a dynamic action that on page load and executes javascript. Find all items with class .a-TreeView-label (assuming that's the class name at runtime that you get as well - check to be sure) and loop over them and for each one, replace its text with itself. This forces it to re-render as HTML. My code in the javascript task:
$(".a-TreeView-label").each(function(index){
$(this).replaceWith($(this).text());
});
On the item attribute "Escape special characters" change to "No"

Update planned order - two committed modifications, only one saved

I need to update two information on one object: the quantity (PLAF-gsmng) and refresh the planned order via the module function 'MD_SET_ACTION_PLAF'.
I successfully find a way to update each data separately. But when I execute the both solutions the second modification is not saved on the database.
Do you know how I can change the quantity & set the action on PLAF (Planned order) table ?
Do you know other module function to update only the quantity ?
Maybe a parameter missing ?
It's like if the second object is locked (sm12 empty, no sy-subrc = locked) ... and the modification is not committed.
I tried to:
change the order of the algorithm (refresh and after, change PLAF)
add, remove, move the COMMIT WORK & COMMIT WORK AND WAIT
add DEQUEUE_ALL or DEQUEUE_EMPLAFE
This is the current code:
1) Read the data
lv_plannedorder = '00000000001'
"Read PLAF data
SELECT SINGLE * FROM PLAF INTO ls_plaf WHERE plnum = lv_plannedorder.
2) Update Quantity data
" Standard configuration for FM MD_PLANNED_ORDER_CHANGE
CLEAR ls_610.
ls_610-nodia = 'X'. " No dialog display
ls_610-bapco = space. " BAPI type. Do not use mode 2 -> Action PLAF-MDACC will be autmatically set up to APCH by the FM
ls_610-bapix = 'X'. " Run BAPI
ls_610-unlox = 'X'. " Update PLAF
" Customize values
MOVE p_gsmng TO ls_plaf-gsmng. " Change quantity value
MOVE sy-datlo TO ls_plaf-mdacd. " Change by/datetime, because ls_610-bapco <> 2.
MOVE sy-uzeit TO ls_plaf-mdact.
CALL FUNCTION 'MD_PLANNED_ORDER_CHANGE'
EXPORTING
ecm61o = ls_610
eplaf = ls_plaf
EXCEPTIONS
locked = 1
locking_error = 2
OTHERS = 3.
" Already committed on the module function
" sy-subrc = 0
If I go on the PLAF table, I can see that the quantity is edited. It's working :)
3) Refresh BOM & change Action (MDACC) and others fields
CLEAR ls_imdcd.
ls_imdcd-pafxl = 'X'.
CALL FUNCTION 'MD_SET_ACTION_PLAF'
EXPORTING
iplnum = lv_plannedorder
iaccto = 'BOME'
iaenkz = 'X'
imdcd = ls_imdcd
EXCEPTIONS
illegal_interface = 1
system_failure = 2
error_message = 3
OTHERS = 4.
IF sy-subrc = 0.
COMMIT WORK.
ENDIF.
If I go on the table, no modification (only the modif. of the part 2. can be found on it).
Any idea ?
Maybe because the ls_610-bapco = space ?
It should be possible to update planned order quantity with MD_SET_ACTION_PLAF too, at least SAP Help tells us so. Why don't you use it like that?
Its call for changing the quantity should possibly look like this:
DATA: lt_acct LIKE TABLE OF MDACCTO,
ls_acct LIKE LINE OF lt_acct.
ls_acct-accto = 'BOME'.
APPEND lt_acct.
ls_acct-accto = 'CPOD'.
APPEND lt_acct.
is_mdcd-GSMNG = 'value' "updated quantity value
CALL FUNCTION 'MD_SET_ACTION_PLAF'
EXPORTING
iplnum = iv_plnum
iaenkz = 'X'
IVBKZ = 'X'
imdcd = is_mdcd "filled with your BOME-related data + new quantity
TABLES
TMDACCTO = lt_accto
EXCEPTIONS
illegal_interface = 1
system_failure = 2
error_message = 3.
So there is no more need for separate call of MD_PLANNED_ORDER_CHANGE anymore and no more problems with update.
I used word possibly because I didn't find any example of this FM call in the Web (and SAP docu is quite ambiguous), so I propose this solution just as is, without verification.
P.S. Possible actions are listed in T46AS table, and possible impact of imdcd fields on order can be checked in MDAC transaction. It is somewhat GUI equivalent of this FM for single order.

Compare index of 2 elements in a collection

Issue : I have some issues figuring out a way to select elements in my HTMLDocument which are under a certain point in the page.
In the following code sample, as you can see in the comments, I first select a part of them which respect my queryselector criteria
IEDoc.querySelectorAll("td[width='100'][class='ListMainCent'][rowSpan='1'][colSpan='1']")
In this example I have 10 elements in this collection. Each of this element in contained in a table which is its parent on the 7th degree.
MsgBox TypeName(IEDoc.querySelectorAll("td[width='100'][class='ListMainCent'][rowSpan='1'][colSpan='1']")(2).ParentNode.ParentNode.ParentNode.ParentNode.ParentNode.ParentNode.ParentNode) ' HTMLTable
Some of those elements are in the same table.
You can see here the form which contains all the tables .
Now, the thing is that I want to select the innerHTML of some of those elements only and not all of them. The criterion to know if I one of those 10 elements interests me or not is it's position on the webpage. I want all the elements which are under the message Part Usage. There is only one table containing the Part Usage text and so my idea was to see if the table in which are contained each element has a higher or lower index in the "form" collection.
If the index is higher I want this element, otherwise I discard it.
What I did for this is the following code :
I set the ID Bim to all the tables containing one or more
from the 10 elements.
For Each Element In IEDoc.querySelectorAll("td[width='100'][class='ListMainCent'][rowSpan='1'][colSpan='1']") ' here for all of the 10 numbers found with the queryselectorall we'll find their respective table in the collection (form) and set its Class as "Bim". But since some of the numbers are in the same table, we won't have 10 tables with a classname "Bim" at the end of the process. We'll have only x tables with the classname "Bim"
Element.ParentNode.ParentNode.ParentNode.ParentNode.ParentNode.ParentNode.ParentNode.Class = "Bim"
Next
I set the ID Stop to the table containing the text Part Usage
For Each Element In IEDoc.getElementsByClassName("SectionHead")
If Element.innerHTML = "Part Usage" Then
'MsgBox TypeName(Element.ParentNode.ParentNode.ParentNode)' HTMLTable
Element.ParentNode.ParentNode.ParentNode.ID = "Stop"
End If
Next
I check which tables with the Classname Bim are under (=higher index) the table with the ID Stop. For the table ( there is actually only one) matching the criterion of point 3 I apply IEDoc.querySelectorAll("td[width='100'][class='ListMainCent'][rowSpan='1'][colSpan='1']") inside of them so that I get all the elements in contains and more paricularly their innerHTML.
For Each Element In IEDoc.getElementsByClassName("Bim") ' Here we check all the x tables which have the Classname "Bim"
If Element.indexInTheWholeForm > IEDoc.getElementById("Stop").indexInTheWholeForm Then 'and compare somehow if their index in the (form) collection if higher than the table with the ID "Stop" ( this is similar to checking if the element if lower on the webpage in thic case) ( we only want the element which have a higher index aka under the Part Usage table)
For Each Element2 In Element.querySelectorAll("td[width='100'][class='ListMainCent'][rowSpan='1'][colSpan='1']") ' Now we are in the table which contains the part numbers and we'll look for all the part numbers it contains by applying the queryselectorall again, but this time only in this specific table
array_parts2(iteration2) = Element.querySelectorAll("td[width='100'][class='ListMainCent'][rowSpan='1'][colSpan='1']")(iteration2).innerHTML
ActiveWorkbook.Worksheets(1).Cells(iteration2 + 1, 19) = array_parts2(iteration2)
iteration2 = iteration2 + 1
Next
End If
Next
of course what doesn't work is the indexInTheWholeForm property which doesn't exist. Any ideas on how to do this ?
Thank for reaching that line :)
Untested but I would do something like this (assuming I understood you correctly)
Sub Tester()
Const S_MATCH As String = "td[width='100'][class='ListMainCent'][rowSpan='1'][colSpan='1']"
Dim e, tbl, bHit As Boolean
'...
'load page etc
'...
'get all the matching rows and cycle though them
For Each e In IEDoc.querySelectorAll(S_MATCH)
'did we get to the table of interest yet?
If Not bHit Then
Set tbl = e.ParentNode.ParentNode.ParentNode.ParentNode. _
ParentNode.ParentNode.ParentNode
If IsPartUsageTable(tbl) Then bHit = True
End If
If bHit Then
'we reached the table of interest, so
' do something with e
End If
Next
End Sub
Function IsPartUsageTable(tbl) As Boolean
Dim e, rv As Boolean
For Each e In tbl.getElementsByClassName("SectionHead")
If Element.innerHTML = "Part Usage" Then
rv = True
Exit For
End If
Next
IsPartUsageTable = rv
End Function
Ok, so as unexpected as it sounds, I think I found a solution to my own question. I will confirm you that it works as soon as I have the possibility to run it with my colleague.
So I keep point 1 and 2 from my initial post and I replaced point 3 with the following :
For i = 0 To IEDoc.getElementsByTagName("form")(0).getElementsByTagName("table").length
If IEDoc.getElementsByTagName("form")(0).getElementsByTagName("table")(i).ID = "Stop" Then
index_Part_Usage = i
Position_Part_Usage = index + 1
Exit For
End If
Next
'MsgBox Position_Part_Usage
For i = 0 To IEDoc.getElementsByTagName("form")(0).getElementsByTagName("table").length
If IEDoc.getElementsByTagName("form")(0).getElementsByTagName("table")(i).className = "Bim" Then
index = i
Position = index + 1
If index > index_Part_Usage Then
For Each Element2 In IEDoc.getElementsByTagName("form")(0).getElementsByTagName("table")(i).querySelectorAll("td[width='100'][class='ListMainCent'][rowSpan='1'][colSpan='1']") ' Now we are in the table which contains the part numbers and we'll look for all the part numbers it contains by applying the queryselectorall again, but this time only in this specific table
array_parts2(iteration2) = IEDoc.getElementsByTagName("form")(0).getElementsByTagName("table")(i).querySelectorAll("td[width='100'][class='ListMainCent'][rowSpan='1'][colSpan='1']")(iteration2).innerHTML
ActiveWorkbook.Worksheets(1).Cells(iteration2 + 1, 19) = array_parts2(iteration2)
iteration2 = iteration2 + 1
Next
End If
End If
Next i

MySQL referencing, to avoid repeating myself?

I have this snippet:
SELECT
CASE WHEN
AVG(UNIX_TIMESTAMP(tDone)-UNIX_TIMESTAMP(tIPN))/3600 >= 10
THEN
ROUND(AVG(UNIX_TIMESTAMP(tDone)-UNIX_TIMESTAMP(tIPN))/3600,0)
ELSE
ROUND(AVG(UNIX_TIMESTAMP(tDone)-UNIX_TIMESTAMP(tIPN))/3600,1)
END
FROM
...
Can I do anything to remove the duplication from this? Something along these lines, for instance: (Hypothetical code follows):
SET var = AVG(UNIX_TIMESTAMP(tDone)-UNIX_TIMESTAMP(tIPN))/3600
SELECT
CASE WHEN
var > 10
THEN
ROUND(var,0)
ELSE
ROUND(var,1)
END
FROM
...
With a subquery you can do something like this :
SELECT
CASE WHEN avgtiPN >= 10 THEN ROUND(avgtiPN,0) ELSE ROUND(avgtiPN,1) END
FROM
(SELECT
AVG(UNIX_TIMESTAMP(tDone)-UNIX_TIMESTAMP(tIPN))/3600 AS avgtiPN
FROM
...) AS AVGQuery
But I am still uncertain if it is more readable.
Yes, you can, but variable processing order is undefined for user-defined variables. This reference in the MySQL documentation explains when this works and when it doesnt.