How to get the text from a matched view using Detox? - react-native

I want to test a view that has a list and filtering functionality:
I want to check the text of the first row and save it
Filter using that text
Check again that the same element is rendered
Thing is, when I match and element using element(by.id('some-id')), how can I retrieve info from that element (if it is possible) like the text it contains?

I created the detox-getprops npm package incorporating the hack mentioned by Maxime Helen. It allows retrieving the text and some other (platform-dependent) properties of the element.
const { getText } = require('detox-getprops');
const text = await getText(element(by.id('heading')));
expect(text).toEqual('Step One');
I hope Detox #445 will be resolved soon after which this package can be deprecated.
Update: You can now fetch the text on iOS using the getAttributes method. The detox-getprops library is still needed for Android (tracked using Detox #2083).

Hacky/funny workaround elaborated from this comment:
const readVisibleText = async (testID) => {
try {
await expect(element(by.id(testID))).toHaveText('_unfoundable_text');
throw 'We never should get here unless target element has unfoundable text';
} catch (error) {
if (device.getPlatform() === 'ios') {
const start = `accessibilityLabel was "`;
const end = '" on ';
const errorMessage = error.message.toString();
const [, restMessage] = errorMessage.split(start);
const [label] = restMessage.split(end);
return label;
} else {
// Android to be tested
const start = 'Got:';
const end = '}"';
const errorMessage = error.message.toString();
const [, restMessage] = errorMessage.split(start);
const [label] = restMessage.split(end);
const value = label.split(',');
var combineText = value.find(i => i.includes('text=')).trim();
const [, elementText] = combineText.split('=');
return elementText;
}
}
};

This is currently not supported, the progress is being tracked in this issue.

Related

React Native map "Undefined" is not a function

I'm trying to get data from API
but. I'm getting this error Error Image.
Here is my code.
const [datas, setDatas] = useState(" ");
const res = async () => {
const response = await axios.get("http://hasanadiguzel.com.tr/api/kurgetir");
setDatas(response.data.TCMB_AnlikKurBilgileri);
};
datas.map((item) => {
return (
<KurCard
title={item.Isim}
alis={item.BanknoteBuying}
satis={item.BanknoteSelling}
/>
);
});
How can I solve this?
I'm trying to map() datas, because I need it
Hi #n00b,
The data that datas is initially being set to an empty string, which does not have a map method. First, you need an empty array instead of an empty stringuseState([]). Now you can map.
const [datas, setDatas] = useState([]);
const res = async () => {
const response = await axios.get('http://hasanadiguzel.com.tr/api/kurgetir');
setDatas(response.data.TCMB_AnlikKurBilgileri);
};
{datas.length > 0 &&
datas.map((item) => {
return <KurCard title={item.Isim} alis={item.BanknoteBuying} satis={item.BanknoteSelling}/>
})
}
make sure you data. it has a length greater than 0 before trying to map over it.
Assuming your API request is valid, you would need to actually return something from the component itself and not just the array:
return datas.map((item) => {return <KurCard title={item.Isim} alis={item.BanknoteBuying} satis={item.BanknoteSelling}/>})

How to know when monitorCharacteristic is done with react native ble plx?

I use react-native-ble-plx in my project to communicante with my tool, and I'm trying to monitor one of its characteristics.
The result is rather long so the monitoringCharacteristic function is looping until it has send me everything, but I don't know how to be sure that the loop is done.
Here is my monitoring function :
const scanMyDevice = async (device) => {
const serviceUUID = '569a1-****'
const writeUUID = '569a2-****'
const readUUID = '569a2-****'
await device.discoverAllServicesAndCharacteristics()
await device.characteristicsForService(serviceUUID)
await device.writeCharacteristicWithResponseForService(serviceUUID, writeUUID, 'IzEwCg==')
var tempTrame = ''
const subscription = device.monitorCharacteristicForService(serviceUUID, readUUID, (error, a) => {
if (error) {
console.log(error)
console.log(error.message)
}
else {
tempTrame = tempTrame + base64.decode(a.value)
setTrameResult(tempTrame)
console.log('// INSIDE ///', tempTrame)
}
}, 'idMonitor')
return () => {
subscription.remove();
}
console.log('DONE')
}
In my code, 'DONE' is going to be printed before 'INSIDE trame'.
I tried to put console.log('DONE') inside the return, but then it was never printed.
I tried to put .then( console.log('DONE')) just before return but it sent me an error saying that it has nothing to do here...
Can someone help me please ?
Finally I went around the problem by defining an ending pattern to the info I wanted to send/read via BLE, and then I wrote a loop to continue reading while the ending pattern was not encountered:
let tempTrame = tempTrame + base64.decode(a.value)
let finalTrame = ''
// check if my variable has the end symbols (to be sure that I have all the information) and if it is the first time I get this information
if (tempTrame.includes('#109F')) {
stop = true
// suppress end symbols
tempTrame = tempTrame.replace(endTrame, '')
finalTrame = tempTrame
}
console.log(finalTrame)

TestCafe - Can You Pass ctx (Context) Variables to reporter?

I would like to know if I have a context variable like t.ctx.data, is there a way to get that to write the value of t.ctx.data to the TestCafe JSON reporter (or any reporter)?
My code:
// Called within Express.js by a request coming from req
const testMySite = (req, res) => {
process.env.PARAMS = JSON.stringify(req.body)
let testcafe = null;
console.log(`Running test on ports 1341 and 1342`)
createTestCafe('localhost', 1341, 1342, void 0, true)
.then(tc => {
testcafe = tc;
const runner = testcafe.createRunner()
return runner
.src(`${path.dirname(__filename)}/tests/gisTest.js`)
.browsers('firefox:headless')
.reporter('json', 'report.json')
.run()
})
.then(failedCount => {
testcafe.close()
})
res.json({message: `Success! Scraper has begun to process ${req.body}`});
}
My test code:
import { ClientFunction, Selector } from 'testcafe';
const doc = process.env.PARAMS
const newDoc = JSON.parse(process.env.PARAMS)
console.log(`newDoc (from test)`, newDoc)
// const _id = newDoc._id
let data = newDoc.mydata
fixture `My Fixture`
.page('https://www.mysite.co')
.afterEach(async t => {
await t
// how do I get t.ctx.myData into the reporter??
console.log(`t.ctx.myData: `, t.ctx.myData)
})
test(`My Test`, async t => {
const photoIcon = Selector('div#sbtc div.LM8x9c > span')
const photoFieldForPaste = Selector('input#Ycyxxc')
const searchByImageButton = Selector('td#aoghAf > input')
const targetElement = Selector('div#jHnbRc span:nth-child(2) > a')
await t
.wait(1000)
.click(photoIcon)
.typeText(photoFieldForPaste, data, {paste: true})
.click(searchByImageButton)
if(await targetElement.exists && await targetElement.visible) {
await t.ctx.finalData = targetElement.innerText;
}
await t.ctx.finalData = null;
})
Please see the part // how do I get t.ctx.myData into the reporter??.
I am assuming this is the only place where I could potentially get the data from the test into the reporter but I'm not sure exactly how.
If you know how to get the t.ctx.myData variable as shown in the above code to be written to the JSON reporter, I would highly appreciate it.
Even better would be to have a way to send the t.ctx.myData value into the response.
At present, you can add only static metadata to tests and fixtures. This metadata is available in reports. Please refer to the following article to get details: https://devexpress.github.io/testcafe/documentation/guides/basic-guides/organize-tests.html#specify-test-metadata
As for sending dynamic data to the reporter, we keep this feature in mind, however we cannot give any estimates on this. Please track the following issue: https://github.com/DevExpress/testcafe/issues/3584

Making a value dynamic in Spark AR via Script

Coming from this Question Tweening Colors on Spark AR via Script i now try to make start and end color dynamically bounded. I propably havn't swallowed the whole concept of reactive programming yet, but i tried to make a factory so the value is a function... yet its not working, or only with the initial values. Using the set function and restarting animation doesnt change a thing. What am i missing? Thank you and best regards!
const pink = [.99, .682, .721, 1];
const blue = [.0094, .0092, .501, 1];
const yellow = [0.9372, .7725, 0, 1];
function ColorFactory() {
this.sourceCol = pink;
this.targetCol = blue;
this.set = function (_col1, _col2) {
this.sourceCol = _col1;
this.targetCol = _col2;
}
this.get = function (id) {
switch (id) {
case 'source': return this.sourceCol;
default: return this.targetCol;
}
}
}
var colfac = new ColorFactory();
const timeDriver = Animation.timeDriver(timeDriverParameters);
const rotSampler = Animation.samplers.easeInQuad(0, 35);
const alphaSampler = Animation.samplers.linear(1, 0);
const colSampler = Animation.samplers.linear(colfac.get('source'), colfac.get('target'));
const colorAnimation = Animation.animate(timeDriver, colSampler);
timedriver.start();
//doesnt make change anything, same colors as before:
colfac.set(blue, yellow);
timedriver.reset();
timedriver.start();
So how could i make the set of colors dynamic? Anyone?
The only "good" option for you is to do something like this:
const colors = [];
const driver = A.timeDriver({ durationMilliseconds : 1000 });
// On NativeUI monitor selected index event
ui.selectedIndex.monitor.subscribe(
(val) => {
const sampler = A.samplers.linear(colors[val.oldValue, colors[val.newValue]);
const colorAnimation = A.animate(driver, sampler);
// bind here to shader
})

Testcafe custom reporter doesn't return from this.formatError

I'm trying to implement a custom reporter for testcafe. If there is an error in testcase and this.formatError is called, it is not returning from this.formatError. Just hangs there indefinitely, I need to manually ctrl-c to stop the testcafe process. But if I remove this.formatError and try again it is working. What could be the reason?
Below is the code for reportTestDone()
reportTestDone (name, testRunInfo, meta) {
const errors = testRunInfo.errs;
const warnings = testRunInfo.warnings;
const hasErrors = !!errors.length;
const hasWarnings = !!warnings.length;
const result = hasErrors ? this.chalk.red('failed')
: this.chalk.green('passed');
const title = `${result} ${name} # ${meta.page}`;
this.write(title)
.newline();
if (hasErrors) {
this.write('Errors:')
.newline();
errors.forEach((error, idx) => {
this.setIndent(4)
.write(this.formatError(error, `${idx + 1} `)) //<-- this line is the problem
.write(error.errMsg)
.newline();
});
this.setIndent(0);
}
if (hasWarnings) {
this.newline()
.write('Warnings:');
warnings.forEach(warning => {
this.newline()
.write(warning);
});
}
this.setIndent(0);
}