Automated enough with selenium to be able to create a Tilde Friends account, create an SSB identity, and post a first message. I'm still confused on some things, but this is progress, and I fixed a longstanding issue creating the first identity.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4377 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
5755b61ea6
commit
16155ef746
@ -245,13 +245,16 @@ class TfElement extends LitElement {
|
|||||||
if (confirm("Are you sure you want to create a new identity?")) {
|
if (confirm("Are you sure you want to create a new identity?")) {
|
||||||
await tfrpc.rpc.createIdentity();
|
await tfrpc.rpc.createIdentity();
|
||||||
this.ids = (await tfrpc.rpc.getIdentities()) || [];
|
this.ids = (await tfrpc.rpc.getIdentities()) || [];
|
||||||
|
if (this.ids && !this.whoami) {
|
||||||
|
this.whoami = this.ids[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render_id_picker() {
|
render_id_picker() {
|
||||||
return html`
|
return html`
|
||||||
<tf-id-picker id="picker" selected=${this.whoami} .ids=${this.ids} @change=${this._handle_whoami_changed}></tf-id-picker>
|
<tf-id-picker id="picker" selected=${this.whoami} .ids=${this.ids} @change=${this._handle_whoami_changed}></tf-id-picker>
|
||||||
<button @click=${this.create_identity}>Create Identity</button>
|
<button @click=${this.create_identity} id="create_identity">Create Identity</button>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,7 +296,7 @@ class TfElement extends LitElement {
|
|||||||
let users = this.users;
|
let users = this.users;
|
||||||
if (this.tab === 'news') {
|
if (this.tab === 'news') {
|
||||||
return html`
|
return html`
|
||||||
<tf-tab-news .following=${this.following} whoami=${this.whoami} .users=${this.users} hash=${this.hash} .unread=${this.unread} @refresh=${() => this.unread = []}></tf-tab-news>
|
<tf-tab-news id="tf-tab-news" .following=${this.following} whoami=${this.whoami} .users=${this.users} hash=${this.hash} .unread=${this.unread} @refresh=${() => this.unread = []}></tf-tab-news>
|
||||||
`;
|
`;
|
||||||
} else if (this.tab === 'connections') {
|
} else if (this.tab === 'connections') {
|
||||||
return html`
|
return html`
|
||||||
@ -325,7 +328,6 @@ class TfElement extends LitElement {
|
|||||||
let self = this;
|
let self = this;
|
||||||
|
|
||||||
if (!this.loading && this.whoami && this.loaded !== this.whoami) {
|
if (!this.loading && this.whoami && this.loaded !== this.whoami) {
|
||||||
console.log(`starting loading ${this.whoami} ${this.loaded}`);
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.load().finally(function() {
|
this.load().finally(function() {
|
||||||
self.loading = false;
|
self.loading = false;
|
||||||
|
@ -372,7 +372,7 @@ class TfComposeElement extends LitElement {
|
|||||||
${Object.values(draft.mentions || {}).map(x => self.render_mention(x))}
|
${Object.values(draft.mentions || {}).map(x => self.render_mention(x))}
|
||||||
${this.render_content_warning()}
|
${this.render_content_warning()}
|
||||||
${this.render_attach_app()}
|
${this.render_attach_app()}
|
||||||
<input type="button" value="Submit" @click=${this.submit}></input>
|
<input type="button" id="submit" value="Submit" @click=${this.submit}></input>
|
||||||
<input type="button" value="Attach" @click=${this.attach}></input>
|
<input type="button" value="Attach" @click=${this.attach}></input>
|
||||||
${this.render_attach_app_button()}
|
${this.render_attach_app_button()}
|
||||||
<input type="button" value="Discard" @click=${this.discard}></input>
|
<input type="button" value="Discard" @click=${this.discard}></input>
|
||||||
|
@ -14,7 +14,6 @@ class TfIdentityPickerElement extends LitElement {
|
|||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
let self = this;
|
|
||||||
this.ids = [];
|
this.ids = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ class TfTabNewsElement extends LitElement {
|
|||||||
<div><input type="button" value=${this.new_messages_text()} @click=${this.show_more}></input></div>
|
<div><input type="button" value=${this.new_messages_text()} @click=${this.show_more}></input></div>
|
||||||
<a target="_top" href="#" ?hidden=${this.hash.length <= 1}>🏠Home</a>
|
<a target="_top" href="#" ?hidden=${this.hash.length <= 1}>🏠Home</a>
|
||||||
<div>Welcome, <tf-user id=${this.whoami} .users=${this.users}></tf-user>!</div>
|
<div>Welcome, <tf-user id=${this.whoami} .users=${this.users}></tf-user>!</div>
|
||||||
<div><tf-compose whoami=${this.whoami} .users=${this.users} .drafts=${this.drafts} @tf-draft=${this.draft}></tf-compose></div>
|
<div><tf-compose id="tf-compose" whoami=${this.whoami} .users=${this.users} .drafts=${this.drafts} @tf-draft=${this.draft}></tf-compose></div>
|
||||||
${profile}
|
${profile}
|
||||||
<tf-tab-news-feed id="news" whoami=${this.whoami} .users=${this.users} .following=${this.following} hash=${this.hash} .drafts=${this.drafts} .expanded=${this.expanded} @tf-draft=${this.draft} @tf-expand=${this.on_expand}></tf-tab-news-feed>
|
<tf-tab-news-feed id="news" whoami=${this.whoami} .users=${this.users} .following=${this.following} hash=${this.hash} .drafts=${this.drafts} .expanded=${this.expanded} @tf-draft=${this.draft} @tf-expand=${this.on_expand}></tf-tab-news-feed>
|
||||||
`;
|
`;
|
||||||
|
@ -96,9 +96,9 @@ class TfNavigationElement extends LitElement {
|
|||||||
|
|
||||||
render_login() {
|
render_login() {
|
||||||
if (this?.credentials?.session?.name) {
|
if (this?.credentials?.session?.name) {
|
||||||
return html`<a href="/login/logout?return=${url() + hash()}">logout ${this.credentials.session.name}</a>`;
|
return html`<a id="login" href="/login/logout?return=${url() + hash()}">logout ${this.credentials.session.name}</a>`;
|
||||||
} else {
|
} else {
|
||||||
return html`<a href="/login?return=${url() + hash()}">login</a>`;
|
return html`<a id="login" href="/login?return=${url() + hash()}">login</a>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,11 +704,13 @@ function api_requestPermission(permission, id) {
|
|||||||
|
|
||||||
const k_options = [
|
const k_options = [
|
||||||
{
|
{
|
||||||
|
id: 'allow',
|
||||||
text: '✅ Allow',
|
text: '✅ Allow',
|
||||||
grant: ['allow once', 'allow'],
|
grant: ['allow once', 'allow'],
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 'deny',
|
||||||
text: '❌ Deny',
|
text: '❌ Deny',
|
||||||
grant: ['deny once', 'deny'],
|
grant: ['deny once', 'deny'],
|
||||||
},
|
},
|
||||||
@ -719,6 +721,7 @@ function api_requestPermission(permission, id) {
|
|||||||
for (let option of k_options) {
|
for (let option of k_options) {
|
||||||
let button = document.createElement('button');
|
let button = document.createElement('button');
|
||||||
button.innerText = option.text;
|
button.innerText = option.text;
|
||||||
|
button.id = option.id;
|
||||||
button.onclick = function() {
|
button.onclick = function() {
|
||||||
resolve(option.grant[check.checked ? 1 : 0]);
|
resolve(option.grant[check.checked ? 1 : 0]);
|
||||||
document.body.removeChild(outer);
|
document.body.removeChild(outer);
|
||||||
|
@ -353,8 +353,6 @@ static int _tf_run_task(const tf_run_args_t* args, int index)
|
|||||||
}
|
}
|
||||||
tf_task_set_db_path(task, db_path);
|
tf_task_set_db_path(task, db_path);
|
||||||
tf_task_activate(task);
|
tf_task_activate(task);
|
||||||
if (args->ssb_port)
|
|
||||||
{
|
|
||||||
if (args->zip)
|
if (args->zip)
|
||||||
{
|
{
|
||||||
tf_ssb_import_from_zip(tf_task_get_ssb(task), args->zip, "core", "apps");
|
tf_ssb_import_from_zip(tf_task_get_ssb(task), args->zip, "core", "apps");
|
||||||
@ -363,7 +361,6 @@ static int _tf_run_task(const tf_run_args_t* args, int index)
|
|||||||
{
|
{
|
||||||
tf_ssb_import(tf_task_get_ssb(task), "core", "apps");
|
tf_ssb_import(tf_task_get_ssb(task), "core", "apps");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (tf_task_execute(task, args->script))
|
if (tf_task_execute(task, args->script))
|
||||||
{
|
{
|
||||||
tf_task_run(task);
|
tf_task_run(task);
|
||||||
|
20
src/ssb.c
20
src/ssb.c
@ -239,6 +239,7 @@ typedef struct _tf_ssb_t
|
|||||||
void* hitch_user_data;
|
void* hitch_user_data;
|
||||||
|
|
||||||
tf_ssb_store_queue_t store_queue;
|
tf_ssb_store_queue_t store_queue;
|
||||||
|
int ref_count;
|
||||||
} tf_ssb_t;
|
} tf_ssb_t;
|
||||||
|
|
||||||
typedef struct _tf_ssb_connection_message_request_t
|
typedef struct _tf_ssb_connection_message_request_t
|
||||||
@ -2278,7 +2279,8 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
|
|||||||
ssb->broadcast_timer.data ||
|
ssb->broadcast_timer.data ||
|
||||||
ssb->broadcast_cleanup_timer.data ||
|
ssb->broadcast_cleanup_timer.data ||
|
||||||
ssb->trace_timer.data ||
|
ssb->trace_timer.data ||
|
||||||
ssb->server.data)
|
ssb->server.data ||
|
||||||
|
ssb->ref_count)
|
||||||
{
|
{
|
||||||
uv_run(ssb->loop, UV_RUN_ONCE);
|
uv_run(ssb->loop, UV_RUN_ONCE);
|
||||||
}
|
}
|
||||||
@ -2341,7 +2343,11 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
|
|||||||
}
|
}
|
||||||
if (ssb->loop == &ssb->own_loop)
|
if (ssb->loop == &ssb->own_loop)
|
||||||
{
|
{
|
||||||
uv_loop_close(ssb->loop);
|
int r = uv_loop_close(ssb->loop);
|
||||||
|
if (r != 0)
|
||||||
|
{
|
||||||
|
tf_printf("uv_loop_close: %s\n", uv_strerror(r));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ssb->own_context)
|
if (ssb->own_context)
|
||||||
{
|
{
|
||||||
@ -3568,3 +3574,13 @@ tf_ssb_store_queue_t* tf_ssb_get_store_queue(tf_ssb_t* ssb)
|
|||||||
{
|
{
|
||||||
return &ssb->store_queue;
|
return &ssb->store_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tf_ssb_ref(tf_ssb_t* ssb)
|
||||||
|
{
|
||||||
|
ssb->ref_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tf_ssb_unref(tf_ssb_t* ssb)
|
||||||
|
{
|
||||||
|
ssb->ref_count--;
|
||||||
|
}
|
||||||
|
@ -200,3 +200,6 @@ uint64_t tf_ssb_get_average_thread_time(tf_ssb_t* ssb);
|
|||||||
void tf_ssb_set_hitch_callback(tf_ssb_t* ssb, void (*callback)(const char* name, uint64_t duration_ns, void* user_data), void* user_data);
|
void tf_ssb_set_hitch_callback(tf_ssb_t* ssb, void (*callback)(const char* name, uint64_t duration_ns, void* user_data), void* user_data);
|
||||||
|
|
||||||
tf_ssb_store_queue_t* tf_ssb_get_store_queue(tf_ssb_t* ssb);
|
tf_ssb_store_queue_t* tf_ssb_get_store_queue(tf_ssb_t* ssb);
|
||||||
|
|
||||||
|
void tf_ssb_ref(tf_ssb_t* ssb);
|
||||||
|
void tf_ssb_unref(tf_ssb_t* ssb);
|
||||||
|
@ -1209,6 +1209,7 @@ static void _tf_ssb_rpc_delete_blobs_after_work(uv_work_t* work, int status)
|
|||||||
{
|
{
|
||||||
delete_blobs_work_t* delete = work->data;
|
delete_blobs_work_t* delete = work->data;
|
||||||
tf_ssb_record_thread_time(delete->ssb, (int64_t)delete->thread_id, delete->end_time - delete->start_time);
|
tf_ssb_record_thread_time(delete->ssb, (int64_t)delete->thread_id, delete->end_time - delete->start_time);
|
||||||
|
tf_ssb_unref(delete->ssb);
|
||||||
tf_free(delete);
|
tf_free(delete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1238,6 +1239,7 @@ static void _tf_ssb_rpc_start_delete_blobs(tf_ssb_t* ssb, int delay_ms)
|
|||||||
*timer = (uv_timer_t) { .data = ssb };
|
*timer = (uv_timer_t) { .data = ssb };
|
||||||
uv_timer_init(tf_ssb_get_loop(ssb), timer);
|
uv_timer_init(tf_ssb_get_loop(ssb), timer);
|
||||||
uv_timer_start(timer, _tf_ssb_rpc_start_delete_timer, delay_ms, 0);
|
uv_timer_start(timer, _tf_ssb_rpc_start_delete_timer, delay_ms, 0);
|
||||||
|
tf_ssb_ref(ssb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tf_ssb_rpc_register(tf_ssb_t* ssb)
|
void tf_ssb_rpc_register(tf_ssb_t* ssb)
|
||||||
|
58
tools/autotest.py
Normal file
58
tools/autotest.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
from selenium import webdriver
|
||||||
|
from selenium.webdriver.common.by import By
|
||||||
|
from selenium.webdriver.support import expected_conditions
|
||||||
|
from selenium.webdriver.support.ui import WebDriverWait
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
|
||||||
|
for path in ('out/selenium.sqlite', 'out/selenium.sqlite-shm', 'out/selenium.sqlite-wal'):
|
||||||
|
try:
|
||||||
|
os.unlink(path)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
tf = subprocess.Popen(['out/debug/tildefriends', 'run', '-d', 'out/selenium.sqlite', '-b', '0', '-p', '8888'])
|
||||||
|
|
||||||
|
try:
|
||||||
|
options = webdriver.FirefoxOptions()
|
||||||
|
#options.add_argument('--headless')
|
||||||
|
driver = webdriver.Firefox(options = options)
|
||||||
|
driver.get('http://localhost:8888')
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.LINK_TEXT, 'login').click()
|
||||||
|
driver.find_element(By.ID, 'register').click()
|
||||||
|
driver.find_element(By.ID, 'name').send_keys('test_user')
|
||||||
|
driver.find_element(By.ID, 'password').send_keys('test_password')
|
||||||
|
driver.find_element(By.ID, 'confirm').send_keys('test_password')
|
||||||
|
driver.find_element(By.ID, 'loginButton').click()
|
||||||
|
|
||||||
|
driver.switch_to.frame(driver.find_element(By.ID, 'document'))
|
||||||
|
WebDriverWait(driver, 30).until(expected_conditions.presence_of_element_located((By.LINK_TEXT, 'ssb')))
|
||||||
|
driver.find_element(By.LINK_TEXT, 'ssb').click()
|
||||||
|
driver.switch_to.default_content()
|
||||||
|
|
||||||
|
WebDriverWait(driver, 30).until(expected_conditions.presence_of_element_located((By.ID, 'document')))
|
||||||
|
driver.switch_to.frame(driver.find_element(By.ID, 'document'))
|
||||||
|
WebDriverWait(driver, 30).until(expected_conditions.presence_of_element_located((By.TAG_NAME, 'tf-app')))
|
||||||
|
tf_app = driver.find_element(By.TAG_NAME, 'tf-app').shadow_root
|
||||||
|
WebDriverWait(driver, 30).until(expected_conditions.element_to_be_clickable(tf_app.find_element(By.ID, 'create_identity')))
|
||||||
|
tf_app.find_element(By.ID, 'create_identity').click()
|
||||||
|
alert = WebDriverWait(driver, 30).until(expected_conditions.alert_is_present())
|
||||||
|
alert.accept()
|
||||||
|
|
||||||
|
driver.implicitly_wait(3)
|
||||||
|
#tf_app = driver.find_element(By.TAG_NAME, 'tf-app').shadow_root
|
||||||
|
#WebDriverWait(driver, 30).until(expected_conditions.visibility_of(tf_app.find_element(By.ID, 'tf-tab-news')))
|
||||||
|
tf_tab_news = tf_app.find_element(By.ID, 'tf-tab-news').shadow_root
|
||||||
|
tf_tab_news.find_element(By.ID, 'tf-compose').shadow_root.find_element(By.ID, 'edit').send_keys('Hello, world!')
|
||||||
|
tf_tab_news.find_element(By.ID, 'tf-compose').shadow_root.find_element(By.ID, 'submit').click()
|
||||||
|
|
||||||
|
driver.switch_to.default_content()
|
||||||
|
driver.find_element(By.ID, 'allow').click()
|
||||||
|
|
||||||
|
print('SUCCESS.')
|
||||||
|
finally:
|
||||||
|
driver.close()
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
tf.terminate()
|
Loading…
Reference in New Issue
Block a user