How to use property file as a object repository in Selenium WebDriver Automation? - selenium-webdriver

How to use property files as a object repository in Selenium WebDriver Automation ?
I am seeking for instructions regarding the setup and the steps that need to be done to achieve this.

Create a framework.properties file and store the variables in this way(below are two locators with sample values)
locator1=username
locator2=password
Create a class for loading the properties file. You can use the snippet below:
Note:Path /src/main/resources/com/framework/properties/ is a sample path and may change as per your framework
public class PropertyManager {
private static final Properties PROPERTY = new Properties();
private static final String FRAMEWORKPROPERTIESPATH = "/src/main/resources/com/framework/properties/";
private static final Logger LOGGER = Logg.createLogger();
public static Properties loadPropertyFile(String propertyToLoad) {
try {
PROPERTY.load(new FileInputStream(System.getProperty("user.dir")
+ FRAMEWORKPROPERTIESPATH + propertyToLoad));
} catch (IOException io) {
LOGGER.info(
"IOException in the loadFrameworkPropertyFile() method of the PropertyManager class",
io);
Runtime.getRuntime().halt(0);
}
return PROPERTY;
}
}
When you want to access the variables from the property class, use the snippet below:
private static final Properties LOCATORPROPERTIES = PropertyManager
.loadPropertyFile("framework.properties");
public void click() {
driver.findElement(By.id(LOCATORPROPERTIES.getProperty("locator1")));
}

Create any file & save it with .properties extension
For example - Add new file in eclipse By right click on project > New > File
Add below data in config.properties file and save
Username = Jhon
Password = Qwerty123
Write Below code to access this file
String filepath = "./config.properties" ; // Path of .properties file
File f = new File(filepath);
FileInputStream fs = new FileInputStream(f);
Properties pro = new Properties();
Pro.Load(fs);
pro.getProperty("Username"); // return value "Jhon" return type string
pro.getProperty("Password"); // retun value "Qwerty123" return type string
Also use like -
driver.findelement(By.id("user")).sendKeys(pro.getProperty("Username"));
driver.findelement(By.id("pass")).sendKeys(pro.getProperty("Password"));

Related

Can I change the output path format of Flink Streaming File Sink?

I'm using Pyflink and the Streaming API to sync data into the file system. The path of the output files were like:
-2023-01-28--01
|-part-xxx-0.json
-2023-01-28--03
|-part-xxx-0.json
It seems the output file path format is {year}-{month}-{day}--{hour}/part-xxx-{commit}.json. How can I change the path format to such as {year}/{month}/{day}/{hour}/part-xxx-{commit}.json?
Write a custom class extends DateTimeBucketAssigner and override the path generation logic in the getBucketId method
Here's an example - saving to a path with a prefix as the POJO class name:
public class DateTimeWithClassPrefixBucketAssigner<IN> extends DateTimeBucketAssigner {
....
#Override
public String getBucketId(Object element, Context context) {
if (dateTimeFormatter == null) {
dateTimeFormatter = DateTimeFormatter.ofPattern(formatString).withZone(zoneId);
}
String prefix = element.getClass().getSimpleName();
return prefix + "/" + dateTimeFormatter.format(Instant.ofEpochMilli(context.currentProcessingTime()));
}
}
End covert data format
import java.text.SimpleDateFormat;
...
String input = "2022-01-31--10";
String output = new SimpleDateFormat("{year}/{month}/{day}/{hour}/part-xxx.json").format(
new SimpleDateFormat("yyyy-MM-dd--HH").parse(input)

How to test fluent migrations with an in-process migration runner and a in memory SQLite database

I have just started to use FluentMigration for my current project. I wrote my first migration but I have some trouble writing a unit test for it.
Here is some sample code:
private ServiceProvider CreateServiceProvider()
{
return new ServiceCollection()
.AddLogging(lb => lb.AddFluentMigratorConsole())
.AddFluentMigratorCore()
.ConfigureRunner(
builder => builder
.AddSQLite()
.WithGlobalConnectionString("Data Source=:memory:;Version=3;New=True;")
.WithMigrationsIn(typeof(MigrationOne).Assembly))
.BuildServiceProvider();
}
private void PerformMigrateUp(IServiceScope scope)
{
var runner = scope.ServiceProvider.GetRequiredService<IMigrationRunner>();
runner.MigrateUp(1);
}
[Test]
public void ShouldHaveTablesAfterMigrateUp()
{
var provider = this.CreateServiceProvider();
using (var scope = provider.CreateScope())
{
this.PerformMigrateUp(scope);
// here I'd like to test if tables have been created in the database by the migration
}
}
I don't know how (or if it is possible) to access the current database connection so I can perform a query. Any suggestions would be helpful. Thanks.
Ok, I found a solution. I have to use the Process method of the runner's processor to perform my own sql query.
It looks like this:
private ServiceProvider CreateServiceProvider()
{
return new ServiceCollection()
.AddLogging(lb => lb.AddFluentMigratorConsole())
.AddFluentMigratorCore()
.ConfigureRunner(
builder => builder
.AddSQLite()
.WithGlobalConnectionString(#"Data Source=:memory:;Version=3;New=True;")
.WithMigrationsIn(typeof(MigrationDate20181026113000Zero).Assembly))
.BuildServiceProvider();
}
[Test]
public void ShouldHaveNewVersionAfterMigrateUp()
{
var serviceProvider = this.CreateServiceProvider();
var scope = serviceProvider.CreateScope();
var runner = scope.ServiceProvider.GetRequiredService<IMigrationRunner>();
runner.MigrateUp(1);
string sqlStatement = "SELECT Description FROM VersionInfo";
DataSet dataSet = runner.Processor.Read(sqlStatement, string.Empty);
Assert.That(dataSet, Is.Not.Null);
Assert.That(dataSet.Tables[0].Rows[0].ItemArray[0], Is.EqualTo("Migration1"));
}
This is an old question but an important one. I find it strange that I couldnt find any documentation on this.
In any case here is my solution which I find to be a bit better as you dont need to rely on the runner. Since you dont need that the options open up hugely for constructor arguments.
Firstly make sure you install Microsoft.Data.Sqlite or you will get a strange error.
SQLite in memory databases exist for as long as the connection does - and 1 database per connection on first glance. Actually though there is a way to share the database between connections as long as at least 1 connection is open at all times according to my experiments. You just need to name it.
https://learn.microsoft.com/en-us/dotnet/standard/data/sqlite/connection-strings#sharable-in-memory
So to begin with I created a connection that will stay open until the test finishes. It will be named using Guid.NewGuid() so that subsequent connections will work as expected.
var dbName = Guid.NewGuid().ToString();
var connectionString = $"Data Source={dbName};Mode=Memory;Cache=Shared";
var connection = new SqliteConnection(connectionString);
connection.Open();
After that the crux of running the migrations is the same as previously answered but the connection string uses the named database:
var sp = services.AddFluentMigratorCore()
.ConfigureRunner(fluentMigratorBuilder => fluentMigratorBuilder
.AddSQLite()
.WithGlobalConnectionString(connectionString)
.ScanIn(AssemblyWithMigrations).For.Migrations()
)
.BuildServiceProvider();
var runner = sp.GetRequiredService<IMigrationRunner>();
runner.MigrateUp();
Here is a class I use to inject a connection factory everywhere that needs to connect to the database for normal execution:
internal class PostgresConnectionFactory : IConnectionFactory
{
private readonly string connectionString;
public PostgresConnectionFactory(string connectionString)
{
this.connectionString = connectionString;
}
public DbConnection Create()
{
return new NpgsqlConnection(connectionString);
}
}
I just replaced this (all hail dependency inversion) with:
internal class InMemoryConnectionFactory : IConnectionFactory
{
private readonly string connectionstring;
public InMemoryConnectionFactory(string connectionstring)
{
this.connectionstring = connectionstring;
}
public DbConnection Create()
{
return new SqliteConnection(connectionstring);
}
}
where the connection string is the same named one I defined above.
Now you can simply use that connection factory anywhere that needs to connect to the same in memory database, and since we can now connect multiple times possibilities for integration testing open up.
Here is the majority of my implementation:
public static IDisposable CreateInMemoryDatabase(Assembly AssemblyWithMigrations, IServiceCollection services = null)
{
if (services == null)
services = new ServiceCollection();
var connectionString = GetSharedConnectionString();
var connection = GetPersistantConnection(connectionString);
MigrateDb(services, connectionString, AssemblyWithMigrations);
services.AddSingleton<IConnectionFactory>(new InMemoryConnectionFactory(connectionString));
return services.BuildServiceProvider()
.GetRequiredService<IDisposableUnderlyingQueryingTool>();
}
private static string GetSharedConnectionString()
{
var dbName = Guid.NewGuid().ToString();
return $"Data Source={dbName};Mode=Memory;Cache=Shared";
}
private static void MigrateDb(IServiceCollection services, string connectionString, Assembly assemblyWithMigrations)
{
var sp = services.AddFluentMigratorCore()
.ConfigureRunner(fluentMigratorBuilder => fluentMigratorBuilder
.AddSQLite()
.WithGlobalConnectionString(connectionString)
.ScanIn(assemblyWithMigrations).For.Migrations()
)
.BuildServiceProvider();
var runner = sp.GetRequiredService<IMigrationRunner>();
runner.MigrateUp();
}
private static IDbConnection GetPersistantConnection(string connectionString)
{
var connection = new SqliteConnection(connectionString);
connection.Open();
return connection;
}
Then here is a sample test:
public Test : IDisposable {
private readonly IDisposable _holdingConnection;
public Test() {
_holdingConnection = CreateInMemoryDatabase(typeof(MyFirstMigration).Assembly);
}
public void Dispose() {
_holdingConnection.Dispose();
}
}
You may notice that the static factory returns a custom interface. Its just an interface that extends the normal tooling I inject to repositories, but also implements IDisposable.
Untested bonus for integration testing where you will have a service collection created via WebApplicationFactory or TestServer etc:
public void AddInMemoryPostgres(Assembly AssemblyWithMigrations)
{
var lifetime = services.BuildServiceProvider().GetService<IHostApplicationLifetime>();
var holdingConnection= InMemoryDatabaseFactory.CreateInMemoryDapperTools(AssemblyWithMigrations, services);
lifetime.ApplicationStopping.Register(() => {
holdingConnection.Dispose();
});
}

javafx CheckBoxTreeItem<File> TreeView<File>. How to show only the name of file and not the full path?

Thanks in advance for support...
I'm coding in JavaFx using TreeView class and CheckBoxTreeItem. I want to show in the treeview the CheckBoxTreeItem (File) only the name of Path or File, and all sub, that user choice. All the stuff about selecting path, flush trow work fine, but when I upload this on the treeview the object show the full path of file and not the name. I want only show the name.
To do this I use a class that extend CheckBoxTreeItem:
public class FilePathTreeItem_analisi extends CheckBoxTreeItem<File>
My question is this: When I add this to the TreeView in this way:
TreeView<File> treview_Base;
treview_Base.setCellFactory(CheckBoxTreeCell.<File>forTreeView());
FilePathTreeItem_analisi Ckaggiunto = new FilePathTreeItem_analisi(file.toPath());
.. and other command that correct upload file
Why its show the full path and not only the name?
This is the class of CheckBoxTreeItem:
public class FilePathTreeItem_analisi extends CheckBoxTreeItem<File>
public FilePathTreeItem_analisi(Path file){
super(file.toFile());
dilavoro =file;
this.fullPath=file.toString();
this.setIndependent(false);
//test if this is a directory and set the icon
if(Files.isDirectory(file)){
this.isDirectory=true;
this.setGraphic(new ImageView(folderCollapseImage));
}else{
this.isDirectory=false;
this.setGraphic(new ImageView(fileImage));
}
this.setValue(file.toFile());
... and some listyener and eventHandler...
So my question is: what I have to use in the class that extend CheckBoxTreeItem to show in the TreeView the name of the file and not the entire path?
Use
StringConverter<File> converter = new StringConverter<File>() {
#Override
public String toString(File file) {
return file.getName();
}
#Override
public File fromString(String string) {
// not used by CheckBoxTreeCell:
return null ;
}
};
treview_Base.setCellFactory(tv -> {
CheckBoxTreeCell<File> cell = new CheckBoxTreeCell<>();
cell.setConverter(converter);
return cell ;
});
instead of
treview_Base.setCellFactory(CheckBoxTreeCell.<File>forTreeView());

How to use symmetricDS in Embedded mode

I have the following use case:
A database A (Master) and a database B (slave), located on diferent machines.
I want to synchronize the Database A with Database B.
I want to create a java application using SymmetricDS embedded.
As there is no documentation on how to perform this, i want a sample example or a documentation .
Please help me I'm stuck.
this an example how run the Symmetric engine server in embedded mode , and it works perfectley for me :
public class ClientNode {
private ClientSymmetricEngine cEngine;
private File propFile;
public ClientNode(File file) throws FileNotFoundException, IOException {
propFile = file;
Properties propertiesFile = new Properties();
propertiesFile.load(new FileReader(propFile));
cEngine = new ClientSymmetricEngine(propertiesFile, true);
getcEngine().openRegistration("client", "001");// client is the name of the node group and 001 is the ID
getcEngine().setup();
getcEngine().start();
}
public ClientSymmetricEngine getcEngine() {
return cEngine;
}
public void setcEngine(ClientSymmetricEngine cEngine) {
this.cEngine = cEngine;
}
}
Main class :
public static void main(String[] args) {
try {
new ClientNode(new File("client.properties"));
SymmetricWebServer node = new SymmetricWebServer("master.properties");
node.setWebAppDir("Web");
node.setJoin(false);
node.start();
// this will stop the node
//node.stop();
}catch (Exception e) {
e.printStackTrace();
}
}
Properties files :
client.properties :
external.id=001
engine.name=client-001
sync.url=http\://localhost\:31415/sync/client-001
group.id=client
db.url=jdbc\:mysql\://localhost/easyexchangedb_slave
db.driver=com.mysql.jdbc.Driver
db.user=root
registration.url=http\://localhost\:31415/sync/server
db.password=
master.properties :
external.id=server
engine.name=server
sync.url=http\://localhost\:31415/sync/server
group.id=server
db.url=jdbc\:mysql\://localhost/easyexchangedb_master
db.driver=com.mysql.jdbc.Driver
db.user=root
registration.url=http\://localhost\:31415/sync/server
db.password=
auto.registration=true
There's a section in the documentation about embedding symmetricDs engine into Java SE application: http://www.symmetricds.org/doc/3.6/user-guide/html-single/user-guide.html#deployment-options-embedded

WPF CodedUI test: programmatically launching application

If I record actions to enter in login credentials into a dialog and call this Submit() in say UImap1.uitests. The autogenerated code will look something like this:
public void Launch()
{
#region Variable Declarations
WpfEdit uIUsernameBoxEdit = this.UIOCC600OILoginWindow.UIUsernameBoxEdit;
WpfEdit uIPasswordBoxEdit = this.UIOCC600OILoginWindow.UIPasswordBoxEdit;
WpfButton uIOKButton = this.UIOCC600OILoginWindow.UIOKButton;
#endregion
// Type 'username' in 'usernameBox' text box
uIUsernameBoxEdit.Text = this.LaunchParams.UIUsernameBoxEditText;
// Click 'passwordBox' text box
Mouse.Click(uIPasswordBoxEdit, new Point(63, 13));
// Type '********' in 'passwordBox' text box
Keyboard.SendKeys(uIPasswordBoxEdit, this.LaunchParams.UIPasswordBoxEditSendKeys, true);
// Click 'OK' button
Mouse.Click(uIOKButton, new Point(33, 14));
}
Now, if I manually launch the application under a method decorded with ClassInitialize in my in my CodedUI test class as follows:
[ClassInitialize()]
public static void MyTestInitialize(TestContext context)
{
Process.Start(#"C:\Program Files (x86)\MyCompany\MyApp.exe");
Playback.Wait(2000);
var uimap = new LaunchApplicationMap();
var loginParams = uimap.EnterLoginCredentialsParams;
loginParams.UIUsernameBoxEditText = "username";
loginParams.UIPasswordBoxEditSendKeys = Playback.EncryptText("password
");
uimap.Launch();
Playback.Wait(5000);
}
why do I get the following a null exception as shown below?
This is also the stack trace:
System.NullReferenceException was unhandled by user code
Message=Object reference not set to an instance of an object.
Source=Microsoft.VisualStudio.TestTools.UITest.Framework
StackTrace:
at Microsoft.VisualStudio.TestTools.UITest.Framework.UITestService.TechnologyManagerByName(String technologyName)
at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.ValidateSearchProperties()
at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.FindInternal()
at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.FindControlIfNecessary()
at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.SetProperty(String propertyName, Object value)
at Microsoft.VisualStudio.TestTools.UITesting.WpfControls.WpfEdit.set_Text(String value)
at UITests.UIMaps.LaunchApplicationMapClasses.LaunchApplicationMap.Launch() in C:\dev\OCC600\Source - Copy\Tests\UITests\UIMaps\LaunchApplicationMap.Designer.cs:line 44
at UITests.LogsViewTests.MyTestInitialize(TestContext context) in C:\dev\OCC600\Source - Copy\Tests\UITests\LogsViewTests.cs:line 70
InnerException:
TIA.
You need to initialize the playback engine to use CodedUI outside of a test method. The framework automatically initializes playback/cleanup in the testinitalize/cleanup methods so you don't see it in there.
ClassInitialize/AssemblyInitialize happen before any tests begin so you have to call Playback.Initialize().

Resources