I'm 100% new here, and I'm not sure if anything else is expected before I post this question. But I didn't find anything about this exact issue when searching, so here goes:
I have a Solution framework using Selenium ChromeDriver for automating a web site, and an included Unit Test project for running the tests.
The tests can be run fine from the VS Test Explorer. But when I try running them from the VS console with
MSTest.exe /testcontainer:d:\Source\Workspaces\QA\Automation\Tests\bin\Debug\Tests.dll /resultsfile:d:\QA\testresults\autotests\regressiontests\tests.trx
i get these errors in the results file:
Test method Tests.BasicTests.Data.GetSiteData.GetMyElementId threw exception:
System.Exception: File not found
at Bytescout.Spreadsheet.Spreadsheet.LoadFromFile(String FileName, CacheType Cache, String Delimiter, Encoding Encoding, String Password)
at Bytescout.Spreadsheet.Spreadsheet.LoadFromFile(String FileName)
at TestData.Readers.ExcelByteScout.ExcelFindRows(String url, String sheetname, String value, Int32 col) in d:\Source\Workspaces\QA\FlowAutomation\TestData\Readers\EscelByteScout.cs:line 113
at TestData.SiteData.MyElements.GetElementId(String location, String element) in d:\Source\Workspaces\QA\Automation\TestData\SiteData\MyElements.cs:line 27
at Tests.BasicTests.Data.GetSiteData.GetMyElementId() in d:\Source\Workspaces\QA\Automation\Tests\BasicTests\Data\GetSiteData.cs:line 13
This is complaining about a Project -> Class in the solution which reads test data (user logins, CSS elements...) from an excel file.
and
Initialization method Tests.TestTests.OpenTests.OpenMyLabDrop2.Init threw exception. OpenQA.Selenium.DriverServiceNotFoundException: OpenQA.Selenium.DriverServiceNotFoundException: The chromedriver.exe file does not exist in the current directory or in a directory on the PATH environment variable. The driver can be downloaded at http://chromedriver.storage.googleapis.com/index.html..
at OpenQA.Selenium.DriverService.FindDriverServiceExecutable(String executableName, Uri downloadUrl)
at OpenQA.Selenium.Chrome.ChromeDriverService.CreateDefaultService()
at Common.Selenium.GCDriver.Initialize() in d:\Source\Workspaces\QA\FlowAutomation\Common\Selenium\GCDriver.cs:line 19
at FlowTests.Base.MyLabDrop2Test.Init() in d:\Source\Workspaces\QA\FlowAutomation\FlowTests\Base\MyLabDrop2Test.cs:line 15
this complains about a missing ChromeDriver.exe which is definetely not missing.
I'm not COMPLETELY new to VS and Selenium, but this I don't get, since the tests run fine from VS but complain about missing references from the console.
So I'm pretty sure there's something I'm missing when running the tests from the console, but what?
EDIT:
The relevant code from ExceByteScout.cs:
using System;
using System.Collections.Generic;
using Bytescout.Spreadsheet;
namespace TestData.Readers {
public class ExcelByteScout {
public static List<string> ExcelReturnXYZ(string url, string sheetname, string cell1, string cell2, string cell3) {
Spreadsheet document = new Spreadsheet();
document.LoadFromFile(url);
Worksheet worksheet = document.Workbook.Worksheets.ByName(sheetname);
List<string> cellvalues = new List<string>();
string name = worksheet.Cell(cell1).Value.ToString();
string user = worksheet.Cell(cell2).Value.ToString();
string pass = worksheet.Cell(cell3).Value.ToString();
cellvalues.Add(name);
cellvalues.Add(user);
cellvalues.Add(pass);
document.Close();
return cellvalues;
}
public static string[] ExcelFindRows(string url, string sheetname, string value, int col) {
Spreadsheet document = new Spreadsheet();
Worksheet worksheet = null;
List<string> values = new List<string>();
string[] userdata = null;
try {
document.LoadFromFile(url);
}
catch (System.Exception ex) {
System.Diagnostics.Debug.WriteLine(ex.Message);
throw;
}
try {
worksheet = document.Workbook.Worksheets.ByName(sheetname);
}
catch (System.NullReferenceException nrex) {
System.Diagnostics.Debug.WriteLine(nrex.Message);
throw;
}
int i = 0;
while (!worksheet.Cell(i, col).ValueAsString.Equals("")) {
if (worksheet.Cell(i, col).ValueAsString.Equals(value)) {
int rowcellcount = 0;
for (int y = 0; !worksheet.Cell(i, y).ValueAsString.Equals(""); y++) {
rowcellcount++;
}
userdata = new string[rowcellcount];
for (int x = 0; x < rowcellcount; x++) {
userdata[x] = worksheet.Cell(i, x).ValueAsString;
}
break;
}
i++;
}
document.Close();
return userdata
}
UPDATE:
The FileNotFound problem was due to a relative path.
But the ChromeDriver not found issue is a mystery. Specifically because this has worked before, in a different solution but with the exact same way of running the tests from the console.
Also, I'm standing in the /Debug folder of the project when I run MSTest.exe, and chromedriver.exe IS in this folder. I cannot see where else it needs to be?
File not found usually means that the file is not found on the location you expect it to be. This can happen because you run from an other path or the file is not copied.
Check the url before the line document.LoadFromFile(url); by Console.WriteLine(url). Then copy the excel to the correct location or fix the url.
Related
I have three solution configurations in my UWP solution in Visual Studio:
Development
Staging
Production
Each is a associated with a different web service and auth provider in the configuration files. In my code, how do I tell which one is which? In the past I've explicitly provided DEFINE constants, but there must be a better way by now.
The active solution configuration is stored in the .suo file beneath the .vs directory at the root solution folder. The .suo file has a compound file binary format, which means you can't just parse it with text manipulation tools.
However, using OpenMcdf -- a tool that can be used to manipulate these types of files -- you can easily get the active solution configuration.
Here's a console app I wrote that works. Feel free to adapt the code to your situation:
using OpenMcdf;
using System;
using System.IO;
using System.Linq;
using System.Text;
namespace GetActiveBuildConfigFromSuo
{
internal enum ProgramReturnCode
{
Success = 0,
NoArg = -1,
InvalidFileFormat = -2
}
internal class Program
{
private const string SolutionConfigStreamName = "SolutionConfiguration";
private const string ActiveConfigTokenName = "ActiveCfg";
internal static int Main(string[] args)
{
try
{
ValidateCommandLineArgs(args);
string activeSolutionConfig = ExtractActiveSolutionConfig(
new FileInfo(args.First()));
throw new ProgramResultException(
activeSolutionConfig, ProgramReturnCode.Success);
}
catch (ProgramResultException e)
{
Console.Write(e.Message);
return (int)e.ReturnCode;
}
}
private static void ValidateCommandLineArgs(string[] args)
{
if (args.Count() != 1) throw new ProgramResultException(
"There must be exactly one command-line argument, which " +
"is the path to an input Visual Studio Solution User " +
"Options (SUO) file. The path should be enclosed in " +
"quotes if it contains spaces.", ProgramReturnCode.NoArg);
}
private static string ExtractActiveSolutionConfig(FileInfo fromSuoFile)
{
CompoundFile compoundFile;
try { compoundFile = new CompoundFile(fromSuoFile.FullName); }
catch (CFFileFormatException)
{ throw CreateInvalidFileFormatProgramResultException(fromSuoFile); }
if (compoundFile.RootStorage.TryGetStream(
SolutionConfigStreamName, out CFStream compoundFileStream))
{
var data = compoundFileStream.GetData();
string dataAsString = Encoding.GetEncoding("UTF-16").GetString(data);
int activeConfigTokenIndex = dataAsString.LastIndexOf(ActiveConfigTokenName);
if (activeConfigTokenIndex < 0)
CreateInvalidFileFormatProgramResultException(fromSuoFile);
string afterActiveConfigToken =
dataAsString.Substring(activeConfigTokenIndex);
int lastNullCharIdx = afterActiveConfigToken.LastIndexOf('\0');
string ret = afterActiveConfigToken.Substring(lastNullCharIdx + 1);
return ret.Replace(";", "");
}
else throw CreateInvalidFileFormatProgramResultException(fromSuoFile);
}
private static ProgramResultException CreateInvalidFileFormatProgramResultException(
FileInfo invalidFile) => new ProgramResultException(
$#"The provided file ""{invalidFile.FullName}"" is not a valid " +
$#"SUO file with a ""{SolutionConfigStreamName}"" stream and an " +
$#"""{ActiveConfigTokenName}"" token.", ProgramReturnCode.InvalidFileFormat);
}
internal class ProgramResultException : Exception
{
internal ProgramResultException(string message, ProgramReturnCode returnCode)
: base(message) => ReturnCode = returnCode;
internal ProgramReturnCode ReturnCode { get; }
}
}
Download DTE nuget packages : EnvDTE.8.0.2
Add below code
EnvDTE.DTE DTE = Marshal.GetActiveObject("VisualStudio.DTE.15.0") as EnvDTE.DTE;
var activeConfig = (string)DTE.Solution.Properties.Item("ActiveConfig").Value;
I need to make a python code available as WCF for another application to access it. The python code was build by the data science team and have no ability to change it. I tried running the program as a process shell but it gives 'System.InvalidOperationException' exception.
I created the same program as C# console application and it works fine. The question is
a. Is this the right way to go about making python code available to another application (REST API is not an option).
b. What is the issue with my code.
public string ClassifyText(string value)
{
string textoutput = "";
string exeFileName = HttpContext.Current.Server.MapPath("~/python.exe");
string argName = HttpContext.Current.Server.MapPath("~/predictionscript.py");
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = exeFileName;
start.Arguments = argName;
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
textoutput = result;
}
}
return textoutput;
}
I'm trying to create Internal Accounts programmaticaly by using proc metadata.
The code section below creates person with External Login.
put"<Person Name=%str(%')&&PersonName&i.%str(%')>";
put"<Logins>";
put"<Login Name=%str(%')Login.&&PersonName&i.%str(%') Password=%str(%')&&word&i.%str(%')/>";
put"</Logins>";
put"</Person>";
To create ExternalLogin we can set attribute Password, and in SAS Metadata it will be encrypted automaticaly.
But to create InternalLogin type of object it is necessary to make the hash value of the password and the salt. I know that the standard sas002 encryption method, but in the case of using proc pwencode how to obtain the value of salt?
Is it possible create InternalLogin by using SAS Base?
Thanx.
So on. I found an article that can tell us how to create Stored Process for this problem. My answer is addition to the article.
The approach is base on execute java methods from sas programm.
1. Prerare setPasswd.java class
I've modified class from article. Separate code to connect to metadata server and create InternalLogin
import java.rmi.RemoteException;
import com.sas.metadata.remote.AssociationList;
import com.sas.metadata.remote.CMetadata;
import com.sas.metadata.remote.Person;
import com.sas.metadata.remote.MdException;
import com.sas.metadata.remote.MdFactory;
import com.sas.metadata.remote.MdFactoryImpl;
import com.sas.metadata.remote.MdOMIUtil;
import com.sas.metadata.remote.MdOMRConnection;
import com.sas.metadata.remote.MdObjectStore;
import com.sas.metadata.remote.MetadataObjects;
import com.sas.metadata.remote.PrimaryType;
import com.sas.metadata.remote.Tree;
import com.sas.meta.SASOMI.ISecurity_1_1;
import com.sas.iom.SASIOMDefs.VariableArray2dOfStringHolder;
public class setPasswd {
String serverName = null;
String serverPort = null;
String serverUser = null;
String serverPass = null;
MdOMRConnection connection = null;
MdFactoryImpl _factory = null;
ISecurity_1_1 iSecurity = null;
MdObjectStore objectStore = null;
Person person = null;
public int connectToMetadata(String name, String port, String user, String pass){
try {
serverName = name;
serverPort = port;
serverUser = user;
serverPass = pass;
_factory = new MdFactoryImpl(false);
connection = _factory.getConnection();
connection.makeOMRConnection(serverName, serverPort, serverUser, serverPass);
iSecurity = connection.MakeISecurityConnection();
return 0;
}catch(Exception e){
return 1;
}
}
public setPasswd(){};
public int changePasswd(String IdentityName, String IdentityPassword) {
try
{
//
// This block obtains the person metadata ID that is needed to change the password
//
// Defines the GetIdentityInfo 'ReturnUnrestrictedSource' option.
final String[][] options ={{"ReturnUnrestrictedSource",""}};
// Defines a stringholder for the info output parameter.
VariableArray2dOfStringHolder info = new VariableArray2dOfStringHolder();
// Issues the GetInfo method for the provided iSecurity connection user.
iSecurity.GetInfo("GetIdentityInfo","Person:"+IdentityName, options, info);
String[][] returnArray = info.value;
String personMetaID = new String();
for (int i=0; i< returnArray.length; i++ )
{
System.out.println(returnArray[i][0] + "=" + returnArray[i][1]);
if (returnArray[i][0].compareTo("IdentityObjectID") == 0) {
personMetaID = returnArray[i][1];
}
}
objectStore = _factory.createObjectStore();
person = (Person) _factory.createComplexMetadataObject(objectStore, IdentityName, MetadataObjects.PERSON, personMetaID);
iSecurity.SetInternalPassword(IdentityName, IdentityPassword);
person.updateMetadataAll();
System.out.println("Password has been changed.");
return 0; // success
}
catch (MdException e)
{
Throwable t = e.getCause();
if (t != null)
{
String ErrorType = e.getSASMessageSeverity();
String ErrorMsg = e.getSASMessage();
if (ErrorType == null)
{
// If there is no SAS server message, write a Java/CORBA message.
}
else
{
// If there is a message from the server:
System.out.println(ErrorType + ": " + ErrorMsg);
}
if (t instanceof org.omg.CORBA.COMM_FAILURE)
{
// If there is an invalid port number or host name:
System.out.println(e.getLocalizedMessage());
}
else if (t instanceof org.omg.CORBA.NO_PERMISSION)
{
// If there is an invalid user ID or password:
System.out.println(e.getLocalizedMessage());
}
}
else
{
// If we cannot find a nested exception, get message and print.
System.out.println(e.getLocalizedMessage());
}
// If there is an error, print the entire stack trace.
e.printStackTrace();
}
catch (RemoteException e)
{
// Unknown exception.
e.printStackTrace();
}
catch (Exception e)
{
// Unknown exception.
e.printStackTrace();
}
System.out.println("Failure: Password has NOT been changed.");
return 1; // failure
}
}
2. Resolve depends
Pay attention to imports in class. To enable execute the code below necessary set CLASSPATH enironment variable.
On linux you can add the next command in %SASConfig%/Lev1/level_env_usermods.sh:
export CLASSPATH=$CLASSPATH:%pathToJar%
On Windows you can add/change environment variable by Advanced system settings
So where should you search jar files? They are in folder:
%SASHome%/SASVersionedJarRepository/eclipse/plugins/
Which files i should include in path?
I've include all that used in OMI(Open Metadata Interface).Also I've added log4j.jar (not working without this jar. Your promts will be helpful):
sas.oma.joma.jar
sas.oma.joma.rmt.jar
sas.oma.omi.jar
sas.svc.connection.jar
sas.core.jar
sas.entities.jar
sas.security.sspi.jar
log4j.jar
setPasswd.jar (YOUR JAR FROM THE NEXT STEP!)
Choose files from nearest release. Example:
Here I'm set file from v940m3f (fix release).
Other ways is here.
3. Compile setPasswd.jar
I'm tried use internal javac.exe into SAS, but it's not worked properly. So ou need to download JDK to compile jars. I've create Bat-file:
"C:\Program Files\Java\jdk1.8.0_121\bin\javac.exe" -source 1.7 -target 1.7 setPasswd.java
"C:\Program Files\Java\jdk1.8.0_121\bin\jar" -cf setPasswd.jar setPasswd.class
Paramethers -source and -target will helpful if your version of JDK is upper, that usses in SAS. Version of "sas"-java you can see by:
PROC javainfo all;
run;
Search the next string in log:
java.vm.specification.version = 1.7
4. Finally. SAS Base call
Now we can call Java code by this method (All methods available here):
data test;
dcl javaobj j ("setPasswd");
j.callIntMethod("connectToMetadata", "%SERVER%", "%PORT%", "%ADMIN%", "%{SAS002}HASHPASSORPASS%", rc1);
j.callIntMethod("changePasswd", "testPassLogin", "pass1", rc2);
j.delete();
run;
In log:
UserClass=Normal
AuthenticatedUserid=Unknown
IdentityName=testPass
IdentityType=Person
IdentityObjectID=A56RQPC2.AP00000I
Password has been changed.
Now time to test. Create new user with no passwords.
Execute code:
data test;
dcl javaobj j ("setPasswd");
j.callIntMethod("connectToMetadata", "&server.", "&port.", "&adm", "&pass", rc1);
j.callIntMethod("changePasswd", "TestUserForStack", "Overflow", rc2);
j.delete();
run;
Now our user has InternalLogin object.
Thanx.
I wanted to move some files to the input folder and tried the required code by placing it in configure() method (I had to use Old mapred API, due to some constraints i have).
But, some how the code in configure is not being executed.
I have achieved my requirement though in other better way. Though this is a stupid idea, I wanted to know why it is not being executed. I have checked the job tracker and all variables got the right values
Code:
in main:
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String date = sdf.format(new Date());
if(args[3].toString().equalsIgnoreCase("net")){
imgInpPath = "/user/mapreduce/output/net/"+date+"/";
inputDir = inputDir+"net/";
}
conf.set("imgInpPath", imgInpPath);
conf.set("inputDir", inputDir);
FileInputFormat.setInputPaths(conf,inputDir);
in configure()
inputPath = conf.get("inputDir");
Path inputImgPath = new Path(conf.get("imgInpPath"));
Configuration config = new Configuration();
FileSystem fileSystem = FileSystem.get(config);
inputImgPath = fileSystem.makeQualified(inputImgPath);
FileStatus[] status = fileSystem.listStatus(inputImgPath, new PathFilter(){
#Override
public boolean accept(Path name) {
return name.getName().contains("part");
}});
for(int i=0; i <status.length;i++)
{
Path inpPath = status[i].getPath();
FileUtil.copy(fileSystem, inpPath, fileSystem, new Path(inputPath), true , conf);
}
As i said, required thing is achieved in other way. But, I wanted to know, why this is not being performed, irrespective of the requirement.
I have a website where I am using selenium for integration testing.
I have link there that is generated using multiple variables from page.
I would like to verify the download pop up box is displaying if at all possible, when i am simulating click on link to download the file.
I know i can have JsUnit that will do that for me.
Any ideas?
Selenium is lousy when working with downloads. Clicking the link will get you into trouble.
You could, however, make a request using HttpURLConnection, Apache HttpComponents (or maybe just a file get through URL) for the link specified and assert a 200 OK response. Or try to get the file - this is my favourite tool for this with Selenium.
Thnx to Slanec i have took up your examples.
Ok after investigation I have decided that best solution will be
something along this line.
public int GetFileLenghtFromUrlLocation(string location)
{
int len = 0;
int timeoutInSeconds = 5;
// paranoid check for null value
if (string.IsNullOrEmpty(location)) return 0;
// Create a web request to the URL
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(location);
myRequest.Timeout = timeoutInSeconds * 1000;
myRequest.AddRange(1024);
try
{
// Get the web response
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
// Make sure the response is valid
if (HttpStatusCode.OK == myResponse.StatusCode)
{
// Open the response stream
using (Stream myResponseStream = myResponse.GetResponseStream())
{
if (myResponseStream == null) return 0;
using (StreamReader rdr = new StreamReader(myResponseStream))
{
len = rdr.ReadToEnd().Length;
}
}
}
}
catch (Exception err)
{
throw new Exception("Error saving file from URL:" + err.Message, err);
}
return len;
}