I have the following function piece of code in my ESP8266 based NodeMCU:
snprintf ( temp, 800,
"<html>\
<head>\
<meta http-equiv='refresh' content='25'/>\
<title>NodeMCU DHT11 Sensor \and Relay Board</title>\
<style>\
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
li { margin: 10px 0;}\
</style>\
</head>\
<body>\
<h1>Hello from NodeMCU!</h1>\
<p>Temperature: %02d ℃<br>\
Humidity: %2d %<br></p><ol>\
<li><a href='/control?relay=5&state=%d'>Turn Relay 1 On\/Off</a>\
<li><a href='/control?relay=4&state=%d'>Turn Relay 2 On\/Off</a></ol>\
<p> Uptime: %02d:%02d:%02d </p>\
</body>\
</html>",
t, h, !digitalRead(5), !digitalRead(4), hr, min % 60, sec % 60
);
I want to be able to replace text on with off and vice versa based on the state of pin which comes from digitalRead(5). So I don't have to write Turn Relay 1 On/Off and instead I should get the state using digitalRead(pinNum) and set the text on or off based on state.
The ternary (conditional) operator is your friend here. You could treat it as an inline if-statement. The syntax looks like this
condition ? val1 : val2
The expression will yield a result depending on condition. If the condition is true it will yield val1, otherwise it will yield val2.
You can use this inside of sprintfs argument list to return a string depending on the pin state.
snprintf(temp, 800,
"... <li><a href='/control?relay=5&state=%d'>Turn Relay 1 %s</a><li> ... ",
!digitalRead(5), (digitalRead(5) ? "Off" : "On");
%s is a placeholder for a string and depending on the state of the pin 5 it will be replaced by "On" or "Off"
Related
I am just trying to verifying color for 'footer-top' background image.
Console view for 'footer top' icon is'
Under Styles:
footer .footer-top {
background: #1571c9;
float: left;
margin-top: 55px;
padding: 25px 0;
width: 100%;
Under Elements:
<div class="footer-top">
<div class="sw-layout">
<div class="footer-section">
<h5>More Information</h5>
<ul>
<li>About Us</li>
<li>Contact Us</li>
<li>FAQ</li>
</ul>
</div>
<div class="footer-section hide-for-xs">
<h5>Finance Cards</h5>
<ul>
<div>
<li>Cash Back Finance Cards</li></div>
<li>Points / Rewards Credit Cards</li>
<li>Travel / Air Miles Credit Cards</li>
<li>Islamic Cards</li>
<li>Business Credit Cards</li>
</li>
</ul>
</div><div class="footer-section hide-for-xs">
<h5>Personal Loans</h5>
<ul>
<li>Salary Transfer Loans</li>
<li>Loans Without Salary Transfer
</li>
</ul>
I am using below lines of code :
String FooterTopSectionColour =
driver.findElement(By.className("footer-top")).getCssValue("background");
try {
Assert.assertEquals("#1571c9", FooterTopSectionColour);
System.out.println("Colour matches with : "+
FooterTopSectionColour);
}
catch (Error e)
{e.printStackTrace();
}
In DOM colour is given in Hex value but Selenium is returning in terms of rgb.
You can check below error in console for the same :
java.lang.AssertionError: expected [rgb(21, 113, 201) none repeat scroll 0% 0% / auto padding-box border-box] but found [#1571c9]
at org.testng.Assert.fail(Assert.java:94)
at org.testng.Assert.failNotEquals(Assert.java:513)
at org.testng.Assert.assertEqualsImpl(Assert.java:135)
at org.testng.Assert.assertEquals(Assert.java:116)
at org.testng.Assert.assertEquals(Assert.java:190)
at org.testng.Assert.assertEquals(Assert.java:200)
at tests.homepage.HomePageStepDefinitions.vefify_colour_for_footer_top_section(HomePageStepDefinitions.java:378)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at cucumber.runtime.Utils$1.call(Utils.java:40)
at cucumber.runtime.Timeout.timeout(Timeout.java:16)
at cucumber.runtime.Utils.invoke(Utils.java:34)
at cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:38)
at cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java:37)
at cucumber.runtime.Runtime.runStep(Runtime.java:300)
at cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
at cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:44)
at cucumber.runtime.model.CucumberFeature.run(CucumberFeature.java:165)
at cucumber.api.testng.TestNGCucumberRunner.runCucumber(TestNGCucumberRunner.java:63)
at cucumber.api.testng.AbstractTestNGCucumberTests.feature(AbstractTestNGCucumberTests.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:86)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:643)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:820)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1128)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
at org.testng.TestRunner.privateRun(TestRunner.java:782)
at org.testng.TestRunner.run(TestRunner.java:632)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:366)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:361)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:319)
at org.testng.SuiteRunner.run(SuiteRunner.java:268)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1244)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
at org.testng.TestNG.run(TestNG.java:1064)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
So, How can I debug it?
Please once check the code which I have used is correct or not!
And also let me know how to convert hex to rgb and compare it by using selenium? Thanks!
As your DOM colour and the CSS colours are different, you need to convert one format to to other and then you need to compare or assert it.
In the below code, I have added the steps which will convert the RGB values into an Hexa decimal and then assert the condition. And I assume that, if you print 'footerTopSelectionColour' value then it prints in the below format :
rgb(21, 113, 201) none repeat scroll 0% 0% / auto padding-box
border-box
Find the modified lines of your code below :
String footerTopSectionColour = driver.findElement(By.className("footer-top")).getCssValue("background");
try {
// I'm assuming that the value of 'footerTopSelectionColour' value will be like below
// rgb(21, 113, 201) none repeat scroll 0% 0% / auto padding-box border-box
// So first we need to convert colour code from rgb to hexa decimal
String value = footerTopSectionColour.trim();
String[] rgbs = value.split("\\)")[0].split("\\(")[1].split(", ");
long r = Long.parseLong(rgbs[0]);
long g = Long.parseLong(rgbs[1]);
long b = Long.parseLong(rgbs[2]);
String hex = String.format("#%02x%02x%02x", r, g, b);
System.out.println("=> The hex conversion is : "+hex);
// After converting you can assert like below
Assert.assertEquals("#1571c9", hex);
System.out.println("Colour matches with : "+ footerTopSectionColour);
} catch (Exception e) {
e.printStackTrace();
}
I hope this answer helps...
Above ans is working fine in converting value from rgb to hexa but assert statement is failed.
footerTopSectionColour colour is : rgb(21, 113, 201) none repeat scroll 0% 0% / auto padding-box border-box
The hex conversion is : #1571c9
Assert.assertEquals(hex, footerTopSectionColour);
Above line of code is throwing error as it is comparing 2 dissimilar values. So instead , use below assert statement to verify it and it works fine.
Assert.assertEquals("#1571c9", hex);
I got a simple grid used like this :
<div id="planningGridDiv"
class="gridPatientContent"
style="height: 450px;min-height: 300px;"
ng-style="{height: showScores ? '150px': '450px'}"
ui-grid-resize-columns
ui-grid-selection
ui-grid-cellNav
ui-grid-pinning
ui-grid="myData"
class="grid">
</div>
But when showScores is true and height pass from 450 to 150 px, the grid itself doesn't shrink.
The first container see its height changed, but this part no :
<div role="grid" ui-grid-one-bind-id-grid="'grid-container'" class="ui-grid-render-container ng-isolate-scope ui-grid-render-container-body" ng-style="{ 'margin-left': colContainer.getMargin('left') + 'px', 'margin-right': colContainer.getMargin('right') + 'px' }" ui-grid-render-container="" container-id="'body'" col-container-name="'body'" row-container-name="'body'" bind-scroll-horizontal="true" bind-scroll-vertical="true" enable-horizontal-scrollbar="grid.options.enableHorizontalScrollbar" enable-vertical-scrollbar="grid.options.enableVerticalScrollbar" aria-multiselectable="true" id="1490734763451-grid-container" style="margin-left: 180px; margin-right: 80px;">
I can't find any solution on doc nor stack overflow, but it seems to me that it should. I can use some help for some pointers.
FYI, I found a solution on another stackoverflow question, but I changed it a bit to fit my needs :
$scope.showScoreDiv = function()
{
$scope.showScores = !$scope.showScores;
$timeout(function(){
$scope.gridApi.grid.handleWindowResize();
}, 1);
};
So the main idea is to change the height via ng-style on the grid div, and when you fire your event, here showScores = true called by showScoreDiv(), you have to call gridApi.grid.handleWindowResize().
The timeout is just here to give some time to the div to be set to the good height before calling handleWindowResize().
I'm sure it's something simple, but I can't seem to figure it out. I am basically trying to use c++ to produce an HTML string and to return it to be stored in an objective c model class to be used later in a web view.
The c++ side of it seems to run fine. here's the method that's called in a cpp file:
const char *SqliteConnection::htmlTest(){
HtmlItemValueTableBuilder htmlBuilder = HtmlItemValueTableBuilder();
std::string s = htmlBuilder.test();
cout << "TEST RESULT: " <<s;
return s.c_str();
}
The cout produces the following output (which is what I want):
TEST RESULT: <!doctype html><html><head></head><div><STYLE type="text/css"> body { margin: 10%; } table { border-spacing: 5px; } td { background-color: #EFEFEF; font-size: 20px; padding: 4px; padding-left: 4px; padding-right: 4px; } tr { margin-bottom: 10px; margin-top: 10px; } </STYLE><table><thead></thead><tbody>
<tr><td>hello</td><td>world</td></tr>
</tbody></table></div></html>
The below is the code the calls it in a separate Objective c++ (.mm) file:
-(NSString *)getFieldsMapAsHtmlForResult:(Result *)result {
const char *s = _sqliteConnection->htmlTest();
NSLog(#"Before Conversion: %s", s);
NSString *htmlString = [NSString stringWithUTF8String:s];
NSLog(#"After Conversion: %#",htmlString);
return htmlString;
}
I have seen a lot of people recommend using stringWithUTF8String to convert a c string to an NString. This has worked for me in the past but for some reason, in both the NSLog outputs, I get nothing returned. The string just mysteriously disappears.
Could you recommend what might be causing this?
----- UPDATE ----
Following Retired Ninja's Advice, I tried to make sure that the pointer referenced wasn't to a variable that fell out of scope. I had a Result model c++ class that I was passing on to my obj c++ code successfully. I decided to add a data member, fields_map_as_html, and have the function pass to that instead of to my obj-C++ code.
SqliteConnection::htmlTest() is returning a pointer to a local variable that goes out of scope so it is no longer valid. You could return a `std::string instead and extract the data in the calling function or use some other method to make sure the data hangs around until you use it.
For a project im building a navigation. The table is like this
SELECT TOP 1000
[id]
,[title]
,[action]
,[listOrder]
,[fk_parentId]
FROM [portfolio].[dbo].[menu]
Where Fk_parentId refers to a id... to build up a menu with levels. Listorder contains a number
Now i want my navigation to output like this
<ul class="nav nav-list">
<li class="nav-header active">List header</li>
<li class="active">Home</li>
<li>Library</li>
<li>Applications</li>
<li class="nav-header">Another list header</li>
<li>Profile</li>
<li>Settings</li>
<li class="divider"></li>
<li>Help</li>
</ul>
so the nav headers must be detected as a nav header and menu items as child. For now i have this code
public void function main(struct rc) {
queryService = new query();
queryService.setDatasource("portfolio");
result = queryService.execute(sql="SELECT * FROM menu ORDER by listOrder");
// result
GetMenuData = result.getResult();
// Loopen over result
writeOutput("<ul class='nav nav-list>'");
for (i = 1; i LTE GetMenuData.RecordCount; i = (i + 1))
{
// Output
WriteOutput(
"<li><a href='"& GetMenuData[ "action" ][ i ] & "'>" & GetMenuData[ "title" ][ i ] & "</a></li>"
);
}
writeOutput("</ul>'");
}
this results:
<ul class='nav nav-list>'
<li><a href='alk.profile'>PROFILE</a></li>
<li><a href=''>List header</a></li>
<li><a href='main.'>home</a></li>
<li><a href=''>Another List header</a></li>
<li><a href='alh.settings'>settings</a></li>
<li><a href='main.library'>librarY</a></li>
<li><a href='help.main'>Help</a></li>
<li><a href='main.applications'>applications</a></li>
</ul>'
How can I add class header to a "header" <li> like listheader, another list header?
How can i dynamicly add the divider between settings and help?
title action listOrder fk_parentId
Another List header NULL 20 NULL
PROFILE alk.profile 5 539BB1A4-5AB5-4059-93AD-17DD8EABAF60
Help help.main 40 NULL
settings alh.settings 20 539BB1A4-5AB5-4059-93AD-17DD8EABAF60
applications main.applications 50 C5EFAE69-FD2A-4B35-A613-B8D429091A8F
List header NULL 10 NULL
home main. 20 C5EFAE69-FD2A-4B35-A613-B8D429091A8F
librarY main.library 30 C5EFAE69-FD2A-4B35-A613-B8D429091A8F
I can't see how you specify active from what you posted, but the following at least would result in the function returning the list with header classes.
public string function main(struct rc) {
// Set up the return string
var strReturn = '<ul class="nav nav-list">';
// Set up the query
var queryService = new Query(
datasource='portfolio'
);
// Execute and get result, specifying field names
var GetMenuData = queryService.execute(sql='
SELECT
id,
action,
title,
fk_parentId
FROM menu
ORDER by listOrder ASC
').getResult();
// Loop over result
for (var i = 1; i <= GetMenuData.RecordCount; i++) {
// For this result, what classes are needed?
var strClasses = '';
// Header class
if (
Len(GetMenuData['fk_parentId'][ i ]) == 0 // Null / len 0 parent == header
) {
strClasses = ListAppend(strClasses,'nav-header',' ');
}
// Add in some logic here for 'active' later on probably a good idea?
// strClasses = ListAppend(strClasses,'active',' ') if id == active id? May need adjustment to query for parent
if (
Len(strClasses) > 0
) {
strClasses = ' class="'&strClasses&'"';
}
// Output list item
strReturn &= '<li'&strClasses&'>';
// Add href if needed
if (
Len(GetMenuData['action'][ i ]) > 0
) {
strReturn &= '<a href="'&GetMenuData['action'][ i ]&'">';
}
strReturn &= GetMenuData['title'][ i ];
if (
Len(GetMenuData['action'][ i ]) > 0
) {
strReturn &= '</a>';
}
// Close off the list item
strReturn &= '</li>';
}
// End the return string
strReturn &= '</ul>';
// And return it
return strReturn;
}
A few notes on the changes
Changed function to have return type "string" instead of "void" and modified it so it returns a string instead of directly writing. This in general allows more control over where precisely the list would be output.
Added scoping for all variables invoked within the function (using 'var' keyword). Please note that the below example will only work in CF9/railo. If using a previous version then the var definitions need to be at top of the function, if unsure just ask
Left a space to indicate where you would add in logic for flagging "active"
Used i++ in place of i = (i + 1) (see What is the difference between ++i and i++? for some info for what that does)
Used strReturn &= ... to add to string, functionally equivilant to strReturn = strReturn & ....
How could we use regexp (replace) to find all occurrences of the following CSS
code in a long string and remove them (the XMP code is what I added)? Thanks.
<xmp>
body { font-family : "Courier New", Courier, monospace; font-size : 9pt; valign : top; text-align : left; line-height: 9pt }
td {
font-family : "Courier New", Courier, monospace; font-size : 9pt; valign : top; text-align : left; line-height: 9pt }
</xmp>
Assuming that the string you provided is inside myString and all the css code is inside cssString.
cssString = cssString.replace(myString, '');
If you want to remove the "\\ \\" along with the content contained within it ! This is how you do in python:
s="<xmp> your css code</xmp>"
s=re.sub("<xmp>.*</xmp>", " ",s)
output:
>>>s
''
In the code above i am substituting everything that starts with tag and $'.*' basically tells the python interpreter to include all the characters until the end tag and substitutes the entire thing with $" ".
if you want to remove just the content of the tags then:
s="<xmp> your css code</xmp>"
code_inside_xmptag=re.search("<xmp>(*.)</xmp>",string)
s=re.sub(code_inside_xmptag.group(1)," ",string)
Output:
>>>s
<xmp> </xmp>
Over here i am basically searching for the tags and creating a group for the content contained.
I am passing that as the string to be replaced/substituted.
You can read more about Regular Expressions in python : Here