How to get the text from a particular xpath and how to store that in a string using Serenity - serenity-bdd

I want to fetch the text from an xpath and store it in a string.
After entering all inputs and submitting , a new code will get generated and which looks like Customercode: IN02732114(number will dynamic).
Now i want to fetch this code and store it in a string and later I want to use this string in other steps to search the data with this code.
i have used below different snippets to get the text from the xpath.
public static Question customer_code_value() {
return actor -> Text.of(CustomerCreatePage.CUSTOMER_CODE_TEXT).viewedBy(actor).asString().substring(15, 26);
}
String code= customer_code_value(); // trying to store the value in String code
but customer_code_value() method returns in Question and cant store in String.
Need some help on how to get the text and store it in string in Serenity.
Please help me ...

To locate an element, use the Target:
import { Target } from '#serenity-js/protractor';
import { by } from 'protractor';
class CustomerCreatePage {
static customerCode = () =>
Target.the('customer code').located(by.xpath(...));
}
To retrieve the text of an element, use Text
import { Target, Text } from '#serenity-js/protractor';
import { by } from 'protractor';
class CustomerCreatePage {
static customerCode = () =>
Target.the('customer code').located(by.xpath(...));
static customerCodeText = () =>
Text.of(CustomerCreatePage.customerCode())
}
To perform a substring operation, use Question.map:
import { Target, Text } from '#serenity-js/protractor';
import { by } from 'protractor';
class CustomerCreatePage {
static customerCode = () =>
Target.the('customer code').located(by.xpath(...));
static customerCodeText = () =>
Text.of(CustomerCreatePage.customerCode())
.map(actor => value => value.substring(15, 26));
}
To store the value so that it can be reused later, TakeNote of it:
import { actorCalled, TakeNotes, TakeNote, Note } from '#serenity-js/core';
import { BrowseTheWeb } from '#serenity-js/protractor';
import { protractor } from 'protractor';
actorCalled('Sudhir')
.whoCan(
BrowseTheWeb.using(protractor.browser),
TakeNotes.usingAnEmptyNotepad(),
)
.attemptsTo(
TakeNote.of(CustomerCreatePage.customerCodeText).as('customer code'),
// do some other interesting things
Enter.the(Note.of('customer code')).into(someField),
)

Related

Modelina Csharp Generator Add Inheritance

I am playing around with asyncapi/modelina CSharpGenerator. I would like to add inheritance to the generated class something like this
public class UserCreated: IEvent
{
}
Is that possible? Can we add additional dependencies other than the generated ones?
Inheritance is, unfortunately, one of those features that have gotten put on the backburner, and still is.
Fortunately, it is possible to accomplish it, but it does require you to overwrite the entire rendering behavior, which might not be maintainable in the long run. You can find the full example in this PR: https://github.com/asyncapi/modelina/pull/772
const generator = new CSharpGenerator({
presets: [
{
class: {
// Self is used to overwrite the entire rendering behavior of the class
self: async ({renderer, options, model}) => {
//Render all the class content
const content = [
await renderer.renderProperties(),
await renderer.runCtorPreset(),
await renderer.renderAccessors(),
await renderer.runAdditionalContentPreset(),
];
if (options?.collectionType === 'List' ||
model.additionalProperties !== undefined ||
model.patternProperties !== undefined) {
renderer.addDependency('using System.Collections.Generic;');
}
const formattedName = renderer.nameType(model.$id);
return `public class ${formattedName} : IEvent
{
${renderer.indent(renderer.renderBlock(content, 2))}
}`;
}
}
}
]
});
What is happening here is that we create a custom preset for the class renderer and overwrite the entire rendering process of itself.
This will generate based on this input:
public class Root : IEvent
{
private string[] email;
public string[] Email
{
get { return email; }
set { email = value; }
}
}
Regarding dependencies, please see https://github.com/asyncapi/modelina/blob/master/docs/presets.md#adding-new-dependencies. You can do this in the self preset hook.
You can read more about the presets here: https://github.com/asyncapi/modelina/blob/master/docs/presets.md

How do you use the LauncherDiscoveryRequestBuilder to execute a test method that has a parameter of type TestInfo?

I tried out all the different method selectors as seen on this page: https://junit.org/junit5/docs/current/api/org/junit/platform/launcher/core/LauncherDiscoveryRequestBuilder.html
For example tried to do it like so:
selectMethod("org.example.order.OrderTests#test3"),
like so:
selectMethod("org.example.order.OrderTests#test3(TestInfo)"),
or like so: selectMethod("org.example.order.OrderTests#test3(org.junit.jupiter.engine.extension.TestInfoParameterResolver$DefaultTestInfo)")
Each time, no tests are found.
When I only select the class the method resides in, it works: selectClass("org.example.order.OrderTests")
(but I'm looking to call the method explicitly)
I am assuming the behavior is the same for other parameter types that are resolved at runtime by a ParameterResolver.
Your assumption is wrong. You can select one and only one test method.
As you mentioned on this page Discovery Selectors there are a lot of examples.
DiscoverySelectors.selectMethod provide three way to select desired method(s)
public static MethodSelector selectMethod(String className, String methodName, String methodParameterTypes) {
...
}
public static MethodSelector selectMethod(String className, String methodName) {
...
}
and
public static MethodSelector selectMethod(String fullyQualifiedMethodName) throws PreconditionViolationException {
...
}
You've tried to use the last method but the fullyQualifiedMethodName was wrong a little bit. If you take a look on javadoc it will turn up.
Parameter type list must exactly match and every non-primitive types must be fully qualified as well.
In your example the package is missing. Try it like: selectMethod("org.example.order.OrderTests#test3(org.junit.jupiter.api.TestInfo)")
Here is a short test.
package io.github.zforgo.stackoverflow;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.RepetitionInfo;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
public class ClassWithTestInfo {
#Test
void foo() {
}
#Test
void foo(TestInfo info) {
}
#RepeatedTest(3)
void foo(RepetitionInfo info) {
}
}
package io.github.zforgo.stackoverflow;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.engine.descriptor.MethodBasedTestDescriptor;
import org.junit.platform.engine.DiscoverySelector;
import org.junit.platform.engine.FilterResult;
import org.junit.platform.engine.discovery.DiscoverySelectors;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.PostDiscoveryFilter;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
class DiscoveryTest {
#Test
#DisplayName("Should select only the desired method(s)")
void doTEst() {
Assertions.assertAll(
() -> {
var methods = discover(DiscoverySelectors.selectClass(ClassWithTestInfo.class));
Assertions.assertEquals(3, methods.size());
},
() -> {
// your way
var fqmn = "io.github.zforgo.stackoverflow.ClassWithTestInfo#foo(TestInfo)";
var methods = discover(DiscoverySelectors.selectMethod(fqmn));
Assertions.assertEquals(0, methods.size());
},
() -> {
// good way
var fqmn = "io.github.zforgo.stackoverflow.ClassWithTestInfo#foo(org.junit.jupiter.api.TestInfo)";
var methods = discover(DiscoverySelectors.selectMethod(fqmn));
Assertions.assertEquals(1, methods.size());
}
);
}
private List<Method> discover(DiscoverySelector... selectors) {
final List<Method> methodCollector = new ArrayList<>();
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(selectors)
.filters((PostDiscoveryFilter) object -> {
Method m = ((MethodBasedTestDescriptor) object).getTestMethod();
methodCollector.add(m);
return FilterResult.included("Matched");
})
.build();
LauncherFactory.create().discover(request);
return methodCollector;
}
}

How to declare model class in react native and pass whole model class in second screen by use of react navigation

Is proper way to declare model class like java and how to pass this into second screen in react native?
export default class UserModel {
stateName;
username;
email;
mobile;
gender;
address;
constructor() {}
setStateName(stateName) {
this.stateName = stateName;
}
setUserName(username) {
this.username = username;
}
setEmail(email) {
this.email = email;
}
setMobile(mobile) {
this.mobile = mobile;
}
setGender(gender) {
this.gender = gender;
}
setAddress(address) {
this.address = address;
}
}
Step 1: Make UserModel.js
class UserModel {
constructor() {
stateName,
username,
email,
mobile,
gender,
address;
}
}
Note: Do not Export it if you don't want to set globally.
Step 2 : Screen1.js - Set UserModel and pass from screen1.
_handlePress = async () => {
UserModel.username = "Vishal Patoliya"
this.props.navigation.navigate('UserList',{userData: UserModel});
}
Step 3 : Receiving model class at another screen.
render() {
console.log(TAG, "render() Called.")
const UserModel = this.props.navigation.getParam('userData');
console.log("Username", UserModel.username)
}
OutPut :
01-16 17:30:32.085 4541 5638 I ReactNativeJS: 'Username', 'Vishal Patoliya'
Edit:
After some discussion, this was required answer:
this.props.navigation.navigate('UserList', { userModel: userModel });
this.props.getParam('userModel', /* optional default value */);
I assume this is your UserModel.js.
Now you are able to import the model like other components:
import UserModel from './location/UserModel';
But if you do it like this, you'd have to instanciate UserModel every time you import it.
If you'd like to prevent this, just instanciate a UserModel and export it inside the UserModel.js and import the instance anywhere.
Like this:
class UserModel {
//...
}
export default new UserModel();
other way might be:
export class UserModel {
//...
}
const GlobalUserModel = new UserModel();
export default GlobalUserModel;
to choose in other files what to import:
import { UserModel } from './location/UserModel'; //get new instance
or
import GlobalUserModel from './location/UserModel'; //get global instance
If imported via { UserModel }, you have to instanciate first: new UserModel()
...or vice versa.

Exposing BLOC streams via fields, methods, or getter

I am using the BLOC pattern for my latest Flutter app and I started out using something like this for my output streams:
class MyBloc {
// Outputs
final Stream<List<Todo>> todos;
factory MyBloc(TodosInteractor interactor) {
final todosController = BehaviorSubject<List<Todo>>()
..addStream(interactor.todos);
return MyBloc._(todosController);
}
MyBloc._(this.todos);
}
but slowly I found myself doing something more like this, using a method (or getter) after awhile:
class MyBloc {
final TodosInteractor _interactor;
// Outputs
Stream<List<Todo>> todos(){
return _interactor.todos;
}
MyBloc(this._interactor) { }
}
For people who want to see... getter for todos in TodosInteractor:
Stream<List<Todo>> get todos {
return repository
.todos()
.map((entities) => entities.map(Todo.fromEntity).toList());
}
When I look at the differing code, I see that the first example uses a field versus a method to expose the stream but I couldn't figure out why I would choose one over the other. It seems to me that creating another controller just to push through the stream is a little much... Is there a benefit to this other than being immutable in my todos stream definition? Or am I just splitting hairs?
Well maybe this will not be a best answer but it is a good practice expose your output stream using get methods. Below a example of a bloc class that i have written to a project using RxDart.
class CityListWidgetBloc {
final _cityInput = PublishSubject<List<Cidade>>();
final _searchInput = new PublishSubject<String>();
final _selectedItemsInput = new PublishSubject<List<Cidade>>();
// exposing stream using get methods
Observable<List<Cidade>> get allCities => _cityInput.stream;
Observable<List<Cidade>> get selectedItems => _selectedItemsInput.stream;
List<Cidade> _searchList = new List();
List<Cidade> _selectedItems = new List();
List<Cidade> _mainDataList;
CityListWidgetBloc() {
//init search stream
_searchInput.stream.listen((searchPattern) {
if (searchPattern.isEmpty) {
_onData(_mainDataList); // resend local data list
} else {
_searchList.clear();
_mainDataList.forEach((city) {
if (city.nome.toLowerCase().contains(searchPattern.toLowerCase())) {
_searchList.add(city);
}
});
_cityInput.sink.add(_searchList);
}
});
}
//getting data from firebase
getCity( {#required String key}) {
FirebaseStateCityHelper.getCitiesFrom(key, _onData);
//_lastKey = key;
}
searchFor(String pattern) {
_searchInput.sink.add(pattern);
}
void _onData(List<Cidade> list) {
_mainDataList = list;
list.sort((a, b) => (a.nome.compareTo(b.nome)));
_cityInput.sink.add(list);
}
bool isSelected(Cidade item) {
return _selectedItems.contains(item);
}
void selectItem(Cidade item) {
_selectedItems.add(item);
_selectedItemsInput.sink.add(_selectedItems);
}
void selectItems(List<Cidade> items){
_selectedItems.addAll( items);
_selectedItemsInput.sink.add( _selectedItems );
}
void removeItem(Cidade item) {
_selectedItems.remove(item);
_selectedItemsInput.sink.add(_selectedItems);
}
dispose() {
_cityInput.close();
_searchInput.close();
_selectedItemsInput.close();
}
}

Aurelia CLI - au run --watch misses obvious type errors

Using AureliaCLI and TypeScript.
I have a service which returns a specific type and a component which incorrectly assigns the returned object to a variable of another type:
import { ItemService } from "./itemService";
import { Item } from '../server/backend';
export class ItemDetails {
item: Item = null;
constructor(private itemService: ItemService) {
}
activate() {
this.item = this.itemService.getItem();
}
}
and
import { Seat } from "../server/backend";
export class ItemService {
item: Seat;
constructor() {
this.item = null;
}
getItem(){
return this.item;
}
setItem(item: Seat){
this.item = item;
}
}
This will generate an error when 'au run --watch' is run the first time, but any subsequent change to either file does not produce an error.
Can I configure AureliaCLI to look at dependant files also?
Thanks
Right, as you can probably guess, I am new to TypeScript.
I forgot to add a return type to the service method...
This will cause the error to be triggered:
getItem(): Seat {
return this.item;
}